??引言??
大家好,我是執梗,藍橋杯的報名快接近尾聲,如果有兄弟還沒報名不了解比賽,缺少視頻講解和真題資源的一定要閱讀一下我的這篇藍橋全決議——藍橋全決議,為了幫助兄弟們更好準備比賽,我特意選取了藍橋往年真題中許多能體現出藍橋經典題型的題目——如暴力遍歷、列舉、動態規劃等等,其中最主要的還是列舉,列舉題目在藍橋杯中是最熱的考點且沒有之一,可以說把列舉練好,就已經半只腳踏入了國賽的大門,有需要的兄弟們可以收藏一下,后續我會繼續更新藍橋真題題型專欄,和大家一起沖擊藍橋杯,下面的真題建議大家先自行思考后再看答案,原題視瞥澩在文章結尾,
📒博客首頁:執梗的博客
🎉歡迎關注🔎點贊👍收藏??留言📝
?? :熱愛Java學習,期待一起交流!
🙏作者水平很有限,如果發現錯誤,求告知,多謝!
🌺有問題可私信交流!!!
??目錄??
🍋1.藍橋刷題須知
🍋2.經典例題講解
🚀1.世紀末的星期(經典日期API問題)
🚀2.馬虎的算式(五個for回圈列舉問題)
🚀3.振興中華(基礎動規問題)
🚀4.猜字母(字符處理問題)
🚀5.立方變自身(簡單列舉)
🚀6.三羊獻瑞(7個for回圈列舉問題)
🚀7.加法變乘法(插乘列舉)
🍋3.藍橋典型列舉問題總結和做題經驗
🍋1.藍橋刷題須知
藍橋杯比賽并不像我們平時在力扣和牛客網刷題一樣,對我們代碼運行和時間有著限制,Java組采用的是eplipse編譯器,C/C++才用的是DevC++,填空題我們需要在編譯器中自己跑出答案,然后直接提交答案即可,所以大家不要擔心什么啊這個代碼難道不會超時嗎,這個代碼空間復雜度也太大了吧,人家只看你的答案是否正確,就算你把電腦跑爛了都沒問題,所以要大膽嘗試,
🍋2.經典例題講解
🚀1.世紀末的星期(經典日期API問題)
題目:有邪教稱1999年12月31日是世界末日,當然謠言已經不攻自破,還有人稱今后的某個世紀末的12月31日,如果是星期一則會....有趣的是,任何一個世紀末的年份的12月31日都不可能是星期一!!!于是"謠言制造商"又修改為星期日.......
1999年12月31日是星期五,請問:未來哪一個離我們最近的一個世紀末年(即XX99年)的12月31日正好是星期天(即星期日)? 回答年份即可
public class 世紀末的星期 {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
for (int year = 1999; year <10000 ; year+=100) {
calendar.set(Calendar.YEAR,year);
calendar.set(Calendar.MONTH,11);//其實是12月
calendar.set(Calendar.DAY_OF_MONTH,31);
if (calendar.get(Calendar.DAY_OF_WEEK)==1) {
//sunday是第一天,所以為1時是Sunday,通過原始碼查看
System.out.println(year);// 2299
break;
}
}
}
}
🔑決議:之所以要講這道經典例題,是因為日期問題是藍橋杯的高頻考點,Java組在這種題目占盡便宜,因為Java中有著Calendar這個日期API,這是非常重要的,它能幾乎解決與日期相關的所有問題,這里我們通過設定年月份,然后判斷是否是星期天,如果是則直接輸出答案,非常簡單,如果這題不使用CalendarAPI的話,還是非常麻煩的,所以Java組的小伙伴一定要學會,
🚀2.馬虎的算式(五個for回圈列舉問題)
題目:小明是個急性子,上小學的時候經常抄錯題目,有一次老師出的36X495=?他卻抄成了396X45?但結果卻很戲劇性,他的答案是正確的!!因為36 * 495= 396 * 45=17280
類似這樣的巧合可能還有很多,比如27 * 594=297 * 54,
假設a b c d e代表1~9不同的五個數字(注意是各不相同的數字,且不含0),能滿足
這樣的格式的式子總共有多少種?
public class 馬虎的算式 {
public static void main(String[] args) {
int count=0;
for (int a = 1; a <= 9; a++) {
for (int b = 1; b <= 9; b++) { //每次for回圈前要判斷前面是否有相等元素
if (a != b) for (int c = 1; c <= 9; c++) {
if (b != c && a != c) for (int d = 1; d <= 9; d++) {
if (a != d && b != d && c != d) for (int e = 1; e <= 9; e++) {
if (a != e && b != e && c != e && d != e) {
if ((a * 10 + b) * (c * 100 + d * 10 + e) == (a * 100 + d * 10 + b) * (c * 10 + e)) {
count++;
}
}
}
}
}
}
}
System.out.println(count);//答案為142
}
}
🔑決議:這是道非常經典的列舉問題,很多人可能會覺得5個for回圈這復雜度也太高了吧,但其實每個回圈都是常數級,即使放到平時的刷題平臺也不會超時,列舉型別的題目,需要大家答案的去實作,列舉當然就是想方設法去列出所有的情況,再判斷是否符合題意,藍橋杯對這種題型是鐘愛有加,就是因為大家平時在各種刷題平臺對這種題遇到比較少,一下緊張,不敢大膽地實作自己的思路,
🚀3.振興中華(基礎動規問題)
題目:小明參加了學校的趣味運動會,其中的一個專案是:跳格子
地上畫著一些格子,每個格子里寫一個字;如下圖
從我做起振
我做起振興
做起振興中
起振興中華
比賽時從左上角的的"從"字開始,只能橫向或縱向跳到相鄰的格子里,但不能跳到對角的格子,要求跳到"華"字結束,要求跳過的路線剛好是"從我做起振興中華"這句話,請問小明有幾種可能的跳躍路線
public class 振興中華 {
public static void main(String[] args) {
int[][] arr=new int[4][5];//注意是四列五縱
for (int i = 0; i < 5; i++) {
arr[0][i]=1;
}
for (int i = 0; i < 4; i++) {
arr[i][0]=1;
}
for (int i = 1; i < 4; i++) {
for (int j = 1; j < 5; j++) {
arr[i][j]=arr[i-1][j]+arr[i][j-1];//狀態轉移方程
}
}
System.out.println(arr[3][4]);//35種
}
}
🔑決議:這是道很簡單的動規問題,當然沒學過動規的兄弟會覺得有點難,沒學過動規的兄弟建議先從斐波那契數列開始學習動規,動規是藍橋杯的高頻考點之一,它出的動規可能會很難也可能會很簡單,所以兄弟們對于簡單的動規問題千萬不能做錯,
🚀4.猜字母(字符處理問題)
題目:
把abcd....s共19個字母組成的序列重復拼接106次,得到長度為2014的串,
接下來洗掉第1個字母(即開頭的字母a),以及第3個,第5個等所有奇數位置的字符,
得到的新串再進行洗掉奇數位置字母的動作,如此下去,最后只剩下一個字母,請寫出該字母,
思路1:采用字串形式
public class 猜字母 {
public static void main(String[] args) {
StringBuilder a=new StringBuilder("abcdefghijklmnopqrs");
//StringBuilder效率更高
for (int i = 1; i <106 ; i++) {
a.append("abcdefghijklmnopqrs");
}
//重復拼接獲得子串
while (a.length()>1){
int l=a.length()/2;
if (a.length()%2!=0) {
l++;
}
for (int i = 0; i <l; i++) {//注意這里是i++不是i+=2,因為待洗掉的陣列下標在變化
a.deleteCharAt(i);
}
}
System.out.println(a);//q
}
}
🔑決議:首先這里我們用的是StringBuider,因為它的效率是最高的,這里我們才用字串的一個好處是它自帶的delete操作可以幫助我們洗掉元素,但正因如此也是我們容易掉坑的地方,當我們洗掉一個元素后,后續的元素會馬上排上來,導致我們本該洗掉的元素的下標變化,導致了刪掉了錯誤的元素,但其實也是有規律的,每洗掉一個元素后,后續所有待洗掉的元素都向左移動一格,比如有個字串abcde,按照要求我們需要刪掉ace這三個,a的下標為0洗掉后,原字串變為bcde,這時本來下標為2的c變成了1,這時我們刪掉c后再下一個待洗掉的元素e下標變為2了,于是本來需要隔一個再洗掉,卻由于下標動態變化就只需要讓i++而不是i+=2了,這里只需要考慮到長度為奇數時需要比偶數多刪一次的問題即可,最后刪剩的字符就是q,
思路2:采用陣列形式
public class 猜字母02 {
public static void main(String[] args) {
char[] a=new char[2014];
int index=0;
for (int i = 0; i < 106; i++) {
for (int j = 0; j < 19; j++) {
a[index++]= (char) ('a'+j);//這里涉及到ascii表的字母轉換
}
}
//采用陣列形式存放
int len=2014;
while (len!=1){
int k=0;
for (int i = 1; i <len ; i+=2) {
a[k++]=a[i];
}
len=k;
}
System.out.println(a[0]);//q
}
}
🔑決議:用陣列形式來做的話更好理解也不容易出錯,把每次需要留下來的元素往前擺,用len來動態地保存這一段的長度,k是待插入的下標,每次需要保存的元素往前放,然后用len更新保留下來的陣列長度,一次次往前移動,不要的元素放陣列后面,最后回圈結束后,陣列的第一個元素就是我們剩下的元素q,
🚀5.立方變自身(簡單列舉)
題目:觀察下面的現象,某個數字的平方,按位累加仍然等于自身
1^3=1
8^3=512 5+1+2=8
17^3=4913 4+9+1+3=17
...
請你計算包括1,8,17在內,符合這個性質的正整數一共有多少個?
public class 立方自身 {
public static void main(String[] args) {
int count = 0;
//其實到最多到100就可以了,也可以加大范圍列舉,會發現答案不會變多
for (int i = 1; i < 100; i++) {
if (sum((int) Math.pow(i, 3)) == i) {
count++;
}
}
System.out.println(count);//6
}
public static int sum(int x){//獲得數x各個位相加的回傳值
int count=0;
while(x>0){
count+=x%10;
x=x/10;
}
return count;
}
}
🔑決議:這道題就是普通的列舉題目,它的列舉范圍也很好確定,當到100的三次方時,數就已經很大了,即使再往后列舉也不會讓答案增多,不過為了更好確定,我們也可以把i的范圍拉大繼續列舉,會發現答案仍然也只有6個,
🚀6.三羊獻瑞(7個for回圈列舉問題)
題目:
觀察下面的加法算式:
祥 瑞 生 輝
+ 三 羊 獻 瑞
————————————
三 羊 生 瑞 氣
![]()
public class 三羊祥瑞 {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
if (i!=j)for (int k = 0; k < 10; k++) {
if (i!=k&&j!=k)for (int l = 0; l < 10; l++) {
if (i!=l&&j!=l&&k!=l)for (int m = 0; m < 10; m++) {
if (i!=m&&j!=m&&k!=m&&l!=m)for (int n = 0; n < 10; n++) {
if (i!=n&&j!=n&&k!=n&&l!=n&&m!=n)for (int o = 0; o < 10; o++) {
if (i!=o&&j!=o&&k!=o&&l!=o&&m!=o&&n!=o){
int x1=i*1000+j*100+k*10+l;
int x2=m*1000+n*100+o*10+j;
if (isOK(x1,x2,i,j,k,l,m,n,o)){
System.out.println(" "+x1);
System.out.println(" "+x2);
System.out.println(x1+x2);
}
}
}
}
}
}
}
}
}
}
public static boolean isOK(int x1,int x2,int i,int j,int k,int l,int m,int n,int o){
int count=x1+x2;
if (count<10000) return false;//如果加起來不是五位數可以直接回傳false
int a=count%10;
if (a==i||a==j||a==k||a==l||a==m||a==n||a==o) return false;
count=count/10;
a=count%10;
if (a!=j) return false;
count=count/10;
a=count%10;
if (a!=k) return false;
count=count/10;
a=count%10;
if (a!=n) return false;
count=count/10;
a=count%10;
if (a!=m) return false;
return true;
}
}


🔑決議:這是一道非常非常經典的藍橋真題列舉問題,最直接最暴力的方法就直接去寫七個for回圈分別將祥瑞生輝三羊獻七個字列舉出來,再寫一個判斷答案是否符合要求的方法,思路很簡單,但是步驟寫起來需要小心,但其實這里我想說的是這里其實是可以優化的,兩個四位數相加得到一個五位數,那么這個這個五位數的萬位只可能是1,也就是三字其實就是1,既然祥加三得進位,三又是1,那么祥肯定就只能是9,進而再可得羊是0,大家可以和上面我貼出的答案對比就能看出來,這樣其實我們的回圈就少了幾層了,但藍橋杯做出答案才是目的,即使是7個for回圈,但其實都是常數級的回圈,瞬間就可以列舉出結果,
🚀7.加法變乘法(插乘列舉)
題目:
![]()
public class 加法變乘法 {
public static void main(String[] args) {
for (int i = 1; i <= 46; i++) {
for (int j = i + 2; j <= 48; j++) {
int count = i * (i + 1) + j * (j + 1);//一定要記得加括號
for (int k = 1; k <= 49; k++) {//將其余的數相加
if (k != i && k != i + 1 && k != j && k != j + 1) {//判斷k不是我們前面已經用來相乘的數
count += k; //將剩余的數加起來
}
}
if (count == 2015) {
System.out.println(i);//得到10 16
}
}
}
}
}
🔑決議:這道題也是經典的插入乘法的列舉問題,比較難處理的是如何進行相加和放乘號的位置,我們需要通過兩個回圈去模擬左右乘號的放入問題,外回圈遍歷左括號可能的位置,內回圈遍歷右括號可能的位置,因為乘號不可以相鄰,所以左括號可能的位置是1的后面到46的后面,右括號每次起始的位置是i+2,最多可以到達48的后面,然后將第一個乘號的乘積加上第二個乘號的乘積得到count,然后遍歷加上剩余的元素最后判斷值是否是我們的2015,最后得到的輸出有10和16,10是題目已經給過的答案,所以另外一個答案就16,
🍋3.藍橋典型列舉問題總結和做題經驗
以上我抽選的都是藍橋杯較容易拿分的列舉填空題,這是我們拿分的關鍵,也是最容易拿分的題目,因為列舉只要你不著急,大膽去嘗試和猜想,耐心的考慮到全部的情況,就一定可以算出答案,也不用去想著怎么去優化代碼,只要能得到答案,就去嘗試,當然得到答案后也一定要去驗證一下,代碼的細節也要把握好,否則很容易得到錯誤答案,最最主要的,還是要多加練習,包括以上的題目和以及視瞥澩我都為大家準備好了,
由于資源視頻和真題鏈接違規,需要的伙伴們直接私信我或者評論,馬上回!!!有用的兄弟們麻煩三連,感謝!!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/390652.html
標籤:java
下一篇:使用縱橫比角度div調整大小

