藍橋杯第9屆國賽真題
1.換零鈔
x星球的鈔票的面額只有:100元,5元,2元,1元,共4種。
小明去x星旅遊,他手裡只有2張100元的x星幣,太不方便,恰好路過x星銀行就去換零錢。
小明有點強迫症,他堅持要求200元換出的零鈔中2元的張數剛好是1元的張數的10倍,
剩下的當然都是5元面額的。銀行的工作人員有點為難,你能幫助算出:在滿足小明要求的前提下,最少要換給他多少張鈔票嗎?
(5元,2元,1元面額的必須都有,不能是0)注意,需要提交的是一個整數,不要填寫任何多餘的內容。
//1元零鈔每多一個 2元零鈔多10個 1元零鈔從1開始增加 當200減去1元與2元的總金額是5的倍數時結束 鈔票最少 int main() { int one = 1, two = 10; int sum; while(++one) { two += 10; if ((200 - one - two * 2) % 5 == 0) { sum = (200 - one - two * 2) / 5 + one + two; break; } } cout << sum; return 0; } // 答案: 74
2.鐳射樣式
x星球的盛大節日為增加氣氛,用30臺機光器一字排開,向太空中打出光柱。
安裝除錯的時候才發現,不知什麼原因,相鄰的兩臺鐳射器不能同時開啟!
國王很想知道,在目前這種bug存在的情況下,一共能打出多少種鐳射效果?顯然,如果只有3臺機器,一共可以成5種樣式,即:
全都關上(sorry, 此時無聲勝有聲,這也算一種)
開一臺,共3種
開兩臺,只1種30臺就不好算了,國王只好請你幫忙了。
要求提交一個整數,表示30臺鐳射器能形成的樣式種數。
注意,只提交一個整數,不要填寫任何多餘的內容。
//f1 dfs搜尋所有可能性 #include <iostream> using namespace std; int l[35]; int ans = 0; void dfs(int index) { if (index == 31) { ans++; return; } if (l[index - 1] == 0) { l[index] = 1; //前一盞燈不亮 則讓當前燈亮 dfs(index + 1); l[index] = 0; } dfs(index + 1); //讓當前燈不亮 } int main() { dfs(1); cout << ans; return 0; } //f2 遞推 int l[35][2]; //l[i][0] 表示一共i盞燈,第i位上的燈不亮共有幾種情況(保證前面的燈都合規則) //l[i][1] 表示一共i盞燈,第i位上的燈亮共有幾種情況 int main(){ l[1][0] = 1; l[1][1] = 1; for(int i = 1; i <= 30; i++){ //第i位不亮則前一盞燈可亮可不亮 l[i][0] = l[i-1][0] + l[i-1][1]; //第i位亮則前一盞燈不能亮 l[i][1] = l[i-1][0]; } //其實就是斐波那契數列 cout<< l[30][0]+[30][1] <<endl; return 0; } //答案 2178309
3.格雷碼
格雷碼是以n位的二進位制來表示數。
與普通的二進位制表示不同的是,它要求相鄰兩個數字只能有1個數位不同。
首尾兩個數字也要求只有1位之差。有很多演算法來生成格雷碼。以下是較常見的一種:
從編碼全0開始生成。
當產生第奇數個數時,只把當前數字最末位改變(0變1,1變0)
當產生第偶數個數時,先找到最右邊的一個1,把它左邊的數字改變。
用這個規則產生的4位格雷碼序列如下:
0000
0001
0011
0010
0110
0111
0101
0100
1100
1101
1111
1110
1010
1011
1001
1000以下是實現程式碼,仔細分析其中邏輯,並填寫劃線部分缺少的程式碼。
請注意:只需要填寫劃線部分缺少的內容,不要抄寫已有的程式碼或符號。
#include <stdio.h>
void show(int a,int n)
{
int i;
int msk = 1;
for(i=0; i<n-1; i++) msk = msk << 1;
for(i=0; i<n; i++){
printf((a & msk)? "1" : "0");
msk = msk >> 1;
}
printf("\n");
}
void f(int n)
{
int i;
int num = 1;
for(i=0; i<n; i++) num = num<<1;
int a = 0;
for(i=0; i<num; i++){
show(a,n);
if(i%2==0){
a = a ^ 1;
}
else{
// a & (-a) (-a)對a取反 求出的是a最右邊一個1 其餘全為0
a = a ^ ((a & (-a)) << 1); //填空
}
}
}
int main()
{
f(4);
return 0;
}