2012第三屆藍橋杯C語言本科組答案【交流貼】


原文地址:http://www.cnblogs.com/CheeseZH/archive/2012/04/07/2436242.html

【有錯誤大家盡管提哈~感謝Muse牧馬指正第1、9題,松鼠123指正第3題,神@雕指正第5題】

1:

    假設有兩種微生物 X 和 Y

X出生后每隔3分鍾分裂一次(數目加倍),Y出生后每隔2分鍾分裂一次(數目加倍)。

一個新出生的X,半分鍾之后吃掉1個Y,並且,從此開始,每隔1分鍾吃1個Y。

現在已知有新出生的 X=10, Y=89,求60分鍾后Y的數目。

如果X=10,Y=90 呢?

本題的要求就是寫出這兩種初始條件下,60分鍾后Y的數目。


題目的結果令你震驚嗎?這不是簡單的數字游戲!真實的生物圈有着同樣脆弱的性質!也許因為你消滅的那只 Y 就是最終導致 Y 種群滅絕的最后一根稻草!

 //Muse牧馬 指證這道題的答案是錯的並給出了代碼。我理解錯了題意,誤以為是“兔子繁殖”了。。。。

X=10 Y=89 : 物種Y會滅絕,所以是0(算出來是一個負數)

X=10 Y=90 : 60min后物種Y最終數量是:94371840(期間Y不可能出現負數)

//代碼:

#include <cstdio> 
int main()
{
long int X=10, Y=90;
for(int k=1; k<=120; k++)//半分鍾一個單位
{
if(k%2==1)Y -= X;//因為X出生半分鍾后就要吃Y,爾后沒1分鍾要吃Y,所以永遠都是奇數個半分鍾的時候吃Y,又因為此時X不會增長(題目為了減小討論的復雜度),所以直接減X數量即可。
if(k%4==0)Y *= 2;//每2分鍾翻倍
if(k%6==0)X *= 2;//每3分鍾翻倍,X和Y的翻倍是相互獨立的,不需要另作討論。
}
printf("%d", Y);
return 0;
}

 

2:

ABCDE * ? = EDCBA

“ABCDE代表不同的數字,問號也代表某個數字!"

 

21978

//5層循環就OK了

3:

有一群海盜(不多於20人),在船上比拼酒量。過程如下:打開一瓶酒,所有在場的人平分喝下,有幾個人倒下了。再打開一瓶酒平分,又有倒下的,再次重復...... 直到開了第4瓶酒,坐着的已經所剩無幾,海盜船長也在其中。當第4瓶酒平分喝下后,大家都倒下了。

等船長醒來,發現海盜船擱淺了。他在航海日志中寫到:“......昨天,我正好喝了一瓶.......奉勸大家,開船不喝酒,喝酒別開船......”

請你根據這些信息,推斷開始有多少人,每一輪喝下來還剩多少人。

如果有多個可能的答案,請列出所有答案,每個答案占一行。

格式是:人數,人數,...

例如,有一種可能是:20,5,4,2,0

 

//松鼠123 告訴我這道題的答案要嚴格遞減的,所以我刪掉了不符合要求的組合。

20 5 4 2 0
18 9 3 2 0
15 10 3 2 0

12 6 4 2 0

//先求處4個數【嚴格遞減的,4層循環就OK】的最小公倍數,然后求倒數和是否為1

4:

    某電視台舉辦了低碳生活大獎賽。題目的計分規則相當奇怪:

每位選手需要回答10個問題(其編號為1到10),越后面越有難度。答對的,當前分數翻倍;答錯了則扣掉與題號相同的分數(選手必須回答問題,不回答按錯誤處理)。

每位選手都有一個起步的分數為10分。

某獲勝選手最終得分剛好是100分,如果不讓你看比賽過程,你能推斷出他(她)哪個題目答對了,哪個題目答錯了嗎?

如果把答對的記為1,答錯的記為0,則10個題目的回答情況可以用僅含有1和0的串來表示。例如:0010110011 就是可能的情況。

你的任務是算出所有可能情況。每個答案占一行。

 

1011010000
0111010000
0010110011

//贏或不贏,只有10道題,遞歸去吧。

5:

順時針轉置矩陣

sizeof(int)*rank*rank
rank-1-i/rank+rank*(i%rank)//經 神@雕 指正。我寫的4而不是rank。應該是rank才對。

void rotate(int* x, int rank) 
{
int* y = (int*)malloc(___________________); // 填空

for(int i=0; i<rank * rank; i++)
{
y[_________________________] = x[i]; // 填空
}

for(i=0; i<rank*rank; i++)
{
x[i] = y[i];
}

free(y);
}

int main(int argc, char* argv[])
{
int x[4][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
int rank = 4;

rotate(&x[0][0], rank);

for(int i=0; i<rank; i++)
{
for(int j=0; j<rank; j++)
{
printf("%4d", x[i][j]);
}
printf("\n");
}

return 0;
}

6:

大數乘法

n3/base+n2/base+n4%base
r[2]/base

void bigmul(int x, int y, int r[]) 
{
int base = 10000;
int x2 = x / base;
int x1 = x % base;
int y2 = y / base;
int y1 = y % base;

int n1 = x1 * y1;
int n2 = x1 * y2;
int n3 = x2 * y1;
int n4 = x2 * y2;

r[3] = n1 % base;
r[2] = n1 / base + n2 % base + n3 % base;
r[1] = ____________________________________________; // 填空
r[0] = n4 / base;

r[1] += _______________________; // 填空
r[2] = r[2] % base;
r[0] += r[1] / base;
r[1] = r[1] % base;
}


int main(int argc, char* argv[])
{
int x[] = {0,0,0,0};

bigmul(87654321, 12345678, x);

printf("%d%d%d%d\n", x[0],x[1],x[2],x[3]);

return 0;
}

7:

6*6棋盤放棋子,使每行每列都是3個(0未放1放了)

NumRow!=3 || NumCol!=3
f(x,r,c+1)
x[r][c]==1

int N = 0; 

bool CheckStoneNum(int x[][6])
{
for(int k=0; k<6; k++)
{
int NumRow = 0;
int NumCol = 0;
for(int i=0; i<6; i++)
{
if(x[k][i]) NumRow++;
if(x[i][k]) NumCol++;
}
if(_____________________) return false; // 填空
}
return true;
}

int GetRowStoneNum(int x[][6], int r)
{
int sum = 0;
for(int i=0; i<6; i++) if(x[r][i]) sum++;
return sum;
}

int GetColStoneNum(int x[][6], int c)
{
int sum = 0;
for(int i=0; i<6; i++) if(x[i][c]) sum++;
return sum;
}

void show(int x[][6])
{
for(int i=0; i<6; i++)
{
for(int j=0; j<6; j++) printf("%2d", x[i][j]);
printf("\n");
}
printf("\n");
}

void f(int x[][6], int r, int c);

void GoNext(int x[][6], int r, int c)
{
if(c<6)
_______________________; // 填空
else
f(x, r+1, 0);
}

void f(int x[][6], int r, int c)
{
if(r==6)
{
if(CheckStoneNum(x))
{
N++;
show(x);
}
return;
}

if(______________) // 已經放有了棋子
{
GoNext(x,r,c);
return;
}

int rr = GetRowStoneNum(x,r);
int cc = GetColStoneNum(x,c);

if(cc>=3) // 本列已滿
GoNext(x,r,c);
else if(rr>=3) // 本行已滿
f(x, r+1, 0);
else
{
x[r][c] = 1;
GoNext(x,r,c);
x[r][c] = 0;

if(!(3-rr >= 6-c || 3-cc >= 6-r)) // 本行或本列嚴重缺子,則本格不能空着!
GoNext(x,r,c);
}
}

int main(int argc, char* argv[])
{
int x[6][6] = {
{1,0,0,0,0,0},
{0,0,1,0,1,0},
{0,0,1,1,0,1},
{0,1,0,0,1,0},
{0,0,0,1,0,0},
{1,0,1,0,0,1}
};

f(x, 0, 0);

printf("%d\n", N);

return 0;
}

8:

這個程序的任務就是把一串拼音字母轉換為6位數字(密碼)。我們可以使用任何好記的拼音串(比如名字,王喜明,就寫:wangximing)作為輸入,程序輸出6位數字。

變換的過程如下:

第一步. 把字符串6個一組折疊起來,比如wangximing則變為:
wangxi
ming

第二步. 把所有垂直在同一個位置的字符的ascii碼值相加,得出6個數字,如上面的例子,則得出:
228 202 220 206 120 105

第三步. 再把每個數字“縮位”處理:就是把每個位的數字相加,得出的數字如果不是一位數字,就再縮位,直到變成一位數字為止。例如: 228 => 2+2+8=12 => 1+2=3

上面的數字縮位后變為:344836, 這就是程序最終的輸出結果!

要求程序從標准輸入接收數據,在標准輸出上輸出結果。

輸入格式為:第一行是一個整數n(<100),表示下邊有多少輸入行,接下來是n行字符串,就是等待變換的字符串。
輸出格式為:n行變換后的6位密碼。

 

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int str[6],istr;
int res[102][6],ires;

void getstr()//read str from stdin
{
char ch;
while((ch=getchar())!='\n')
{
str[istr%6]+=ch;
istr++;
}

}
void cal()//calculate the result
{
int i,t;
for(i=0;i<6;i++)
{
while(str[i]>9)
{
t=str[i];
str[i]=0;
while(t)
{
str[i]+=t%10;
t/=10;
}
}
}
}
void save()//put the result into res array
{
int i;
for(i=0;i<6;i++)
res[ires][i]=str[i];
ires++;
}
void main()
{
int n,i,j;
scanf("%d",&n);
getchar();
while(n--)
{
memset(str,0,sizeof(str));
istr=0;
getstr();
cal();
save();
}
for(i=0;i<ires;i++)//print the res array to stdout
{
for(j=0;j<6;j++) printf("%d",res[i][j]);
printf("\n");
}
}

9:

    足球比賽具有一定程度的偶然性,弱隊也有戰勝強隊的可能。

假設有甲、乙、丙、丁四個球隊。根據他們過去比賽的成績,得出每個隊與另一個隊對陣時取勝的概率表:

甲 乙 丙 丁
甲 - 0.1 0.3 0.5
0.9 - 0.7 0.4
0.7 0.3 - 0.2
0.5 0.6 0.8 -

數據含義:甲對乙的取勝概率為0.1,丙對乙的勝率為0.3,...

現在要舉行一次錦標賽。雙方抽簽,分兩個組比,獲勝的兩個隊再爭奪冠軍。(參見【1.jpg】)

請你進行10萬次模擬,計算出甲隊奪冠的概率。

 【正確思路請看Muse牧馬的評論】
10:

    今盒子里有n個小球,A、B兩人輪流從盒中取球,每個人都可以看到另一個人取了多少個,也可以看到盒中還剩下多少個,並且兩人都很聰明,不會做出錯誤的判斷。

我們約定:

每個人從盒子中取出的球的數目必須是:13,7或者8個。

輪到某一方取球時不能棄權!

A先取球,然后雙方交替取球,直到取完。

被迫拿到最后一個球的一方為負方(輸方)


請編程確定出在雙方都不判斷失誤的情況下,對於特定的初始球數,A是否能贏?

程序運行時,從標准輸入獲得數據,其格式如下:

先是一個整數n(n<100),表示接下來有n個整數。然后是n個整數,每個占一行(整數<10000),表示初始球數。

程序則輸出n行,表示A的輸贏情況(輸為0,贏為1)。

 

【我把10001寫成了101,所以。。。又悲劇了】

#include<stdio.h>
int a[10001];
int r[10001],ir;
void main()
{
int i,n;
a[1]=0;a[2]=1;a[3]=0;a[4]=1;
a[5]=0;a[6]=1;a[7]=0;a[8]=1;
for(i=9;i<=10000;i++)
if(!a[i-1]||!a[i-3]||!a[i-7]||!a[i-8])
a[i]=1;
scanf("%d",&n);
while(n--)
{
scanf("%d",&i);
r[ir++]=a[i];
}
for(i=0;i<ir;i++)
printf("%d\n",r[i]);
}




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM