第一題
代碼填空 (滿分3分)
神秘的三位數
有這樣一個3位數,組成它的3個數字階乘之和正好等于它本身。即:abc = a! + b! + c!
下面的程式用于搜尋這樣的3位數。請補全缺失的代碼。
把填空的答案(僅填空處的答案,不包括題面)存入考生檔案夾下對應題号的“解答.txt”中即可。
int JC[] = {1,1,2,6,24,120,720,5040,40320,362880};
int i;
for(i=100; i<1000; i++)
{
int sum = 0;
int x = i;
while(__________)
{
sum += JC[x%10];
x /= 10;
}
if(i==sum) printf("%d\n", i);
}
答案:x>0
第二題
代碼填空 (滿分4分)
歌賽新規則
歌手大賽的評分規則一般是去掉一個最高分,去掉一個最低分,剩下的分數求平均。當評委較少的時候,如果我們隻允許去掉一個分數,該如何設計規則呢?
有人提出:應該去掉與其餘的分數平均值相差最遠的那個分數。即“最離群”的分數。
以下的程式用于實作這個功能。其中x存放所有評分,n表示數組中元素的個數。函數傳回最“離群”的那個分數值。請補全缺失的代碼。
把填空的答案(僅填空處的答案,不包括題面)存入考生檔案夾下對應題号的“解答.txt”中即可。
double score(doublex[], int n)
{
int i,j;
double dif = -1;
double bad;
for(i=0; i<n; i++)
{
double sum = 0;
for(j=0; j<n; j++)
{
if(________) sum += x[j];
}
double t = x[i] - sum / (n-1);
if(t<0) t = -t;
if(t>dif)
{
dif = t;
bad = x[i];
printf("%d, %f\n", i, x[i]);
}
}
return bad;
}
答案:i!=j
第三題
代碼填空 (滿分4分)
反轉串
我們把“cba”稱為“abc”的反轉串。
下面的代碼可以把buf中的字元反轉。其中n表示buf中待反轉的串的長度。請補充缺少的代碼。
把填空的答案(僅填空處的答案,不包括題面)存入考生檔案夾下對應題号的“解答.txt”中即可。
void reverse_str(char*buf, int n)
{
if(n<2) return;
char tmp = buf[0];
buf[0] = buf[n-1];
buf[n-1] = tmp;
_______________________________;
}
交換完第一個和倒數第一個後,又交換第二個和倒數第二個,依次進行下去。注意比如進行第二個和倒數第二個的交換時,第二個數成為buf的第一個數,那麼倒數第二個數的位置相應減去1位,是以累計要減去2.
答案:reverse_str(buf+1, n-2)
第四題
代碼填空 (滿分5分)
n進制小數
将任意十進制正小數分别轉換成2,3,4,5,6,7,8,9進制正小數,小數點後保留8位,并輸出。例如:若十進制小數為0.795,則輸出:
十進制正小數0.795000 轉換成 2 進制數為: 0.11001011
十進制正小數0.795000 轉換成 3 進制數為: 0.21011011
十進制正小數0.795000 轉換成 4 進制數為: 0.30232011
十進制正小數0.795000 轉換成 5 進制數為: 0.34414141
十進制正小數0.795000 轉換成 6 進制數為: 0.44341530
十進制正小數0.795000 轉換成 7 進制數為: 0.53645364
十進制正小數0.795000 轉換成 8 進制數為: 0.62702436
十進制正小數0.795000 轉換成 9 進制數為: 0.71348853
以下代碼提供了這個功能。其中,dTestNo表示待轉的十進制小數。iBase表示進制數。請填寫缺失的部分。
把填空的答案(僅填空處的答案,不包括題面)存入考生檔案夾下對應題号的“解答.txt”中即可。
void fun(doubledTestNo, int iBase)
{
int iT[8];
int iNo;
printf("十進制正小數 %f 轉換成 %d 進制數為: ",dTestNo, iBase);
for(iNo=0;iNo<8;iNo++)
{
dTestNo *= iBase;
iT[iNo] = ________________;
if(___________________) dTestNo -= iT[iNo];
}
printf("0.");
for(iNo=0; iNo<8; iNo++) printf("%d", iT[iNo]);
printf("\n");
}
void main ( )
{
double dTestNo= 0.795;
int iBase;
for(iBase=2;iBase<=9;iBase++)
fun(dTestNo,iBase);
printf("\n");
}
答案:
(int)dTestNo
dTestNo
第五題
代碼填空 (滿分6分)
輪換
串“abcd”每個字元都向右移位,最右的移動到第一個字元的位置,就變為“dabc”。這稱為對串進行位移=1的輪換。同理,“abcd”變為:“cdab”則稱為位移=2的輪換。
下面的代碼實作了對串s進行位移為n的輪換。請補全缺失的代碼。
把填空的答案(僅填空處的答案,不包括題面)存入考生檔案夾下對應題号的“解答.txt”中即可。
void shift(char* s, intn)
{
char* p;
char* q;
int len = strlen(s);
if(len==0) return;
if(n<=0 || n>=len) return;
char* s2 = (char*)malloc(_________);
p = s;
q = s2 + n % len;
while(*p)
{
*q++ = *p++;
if(q-s2>=len)
{
*q = ___________;
q = s2;
}
}
strcpy(s,s2);
free(s2);
}
答案:
(len+1)*sizeof(char)
'\0'
第六題
代碼填空 (滿分9分)
中獎計算
某抽獎活動的規則是:每位參與者在紙上寫下一個8位數的号碼。最後通過搖獎的辦法随機産生一個8位數字。參與者寫下的數字中最多有多少個連續位與開獎号碼中的相同,則稱為中了幾個号。
例如:小張寫的數字是:12345678,而開獎号碼是:42347856。則稱小張中了3個号,因為其中最長的相同連續位是:“234”。如果小張寫的是:87654321,則他隻中了一個号。
下面的代碼根據傳入的參數,傳回中了幾個号。其中:a表示被評價的号碼,b表示搖号産生的數字。請填寫缺少的代碼。
把填空的答案(僅填空處的答案,不包括題面)存入考生檔案夾下對應題号的“解答.txt”中即可。
int g(int a, int b)
{
char sa[]="00000000";
char sb[]="00000000";
int n = 0;
int i,j;
sprintf(sa,"%8d",a);
sprintf(sb,"%8d",b);
for(i=0; i<8; i++)
{
for(j=1; j<=8-i; j++)
{
char t = ________;
sa[i+j] = 0;
if(strstr(sb, sa+i))
{
if(j>n) _________;
}
sa[i+j] = t;
}
}
return n;
}
答案:
sa[i+j]
n=j
第七題
代碼填空 (滿分10分)
機率問題
某個袋子中有紅球m個,白球n個。現在要從中取出x個球。那麼紅球數目多于白球的機率是多少呢?
下面的代碼解決了這個問題。其中的y表示紅球至少出現的次數。
這與前文的問題是等價的。因為如果取30個球,要求紅球數大于白球數,則等價于至少取出16個紅球。請根據僅存的線索,判斷程式邏輯,并補全缺少的代碼。
把填空的答案(僅填空處的答案,不包括題面)存入考生檔案夾下對應題号的“解答.txt”中即可。
double pro(int m, intn, int x, int y)
{
if(y>x) return 0;
if(y==0) return 1;
if(y>m) return 0;
if(x-n>y) return 1;
double p1 = _______________________;
double p2 = _______________________;
return (double)m/(m+n) * p1 + (double)n/(m+n) * p2;
}
答案:
pro(m-1,n,x-1,y-1)
pro(m,n-1,x-1,y)
第八題
程式設計(滿分15分)
方陣的主對角線之上稱為“上三角”。
請你設計一個用于填充n階方陣的上三角區域的程式。填充的規則是:使用1,2,3….的自然數列,從左上角開始,按照順時針方向螺旋填充。
例如:當n=3時,輸出:
1 2 3
6 4
5
當n=4時,輸出:
1 2 3 4
9 10 5
8 6
7
當n=5時,輸出:
1 2 3 4 5
12 13 14 6
11 15 7
10 8
9
程式運作時,要求使用者輸入整數n(3~20)
程式輸出:方陣的上三角部分。
要求格式:每個資料寬度為4,右對齊。
要求考生把所有函數寫在一個檔案中。調試好後,存入與考生檔案夾下對應題号的“解答.txt”中即可。相關的工程檔案不要拷入。
對于程式設計題目,要求選手給出的解答完全符合ANSI C标準,不能使用c++特性;不能使用諸如繪圖、中斷調用等硬體相關或作業系統相關的API。
三角螺旋陣的規律是順時針數字從1開始遞增的,是以我們也可以按照一圈一圈來将依次遞增的數賦給一個二維數組,然後輸出倒三角的數組即可。
<span style="font-size:14px;">#include<stdio.h>
int a[20][20];
int main()
{
int n;
while(~scanf("%d",&n))
{
int i,j,circle=1;//circle記錄進行到了第幾圈
int pos=1;
while(pos<=n*(n+1)/2)
{
for(i=circle,j=circle; j<=n-(circle-1)*2; j++)//橫向向右指派
a[i][j]=pos++;
for(i=circle+1,j=n-(circle-1)*2-1; i<=n-(circle-1)*2&&j>=circle; i++,j--)//對角線左下向指派
a[i][j]=pos++;
for(i=n-(circle-1)*2-1,j=circle; i>=circle+1; i--)//豎向向上指派
a[i][j]=pos++;
circle++;
}
for(i=1; i<=n; i++)//倒三角輸出
{
for(j=1; j<=n-i+1; j++)
printf("%4d",a[i][j]);
printf("\n");
}
}
return 0;
} </span>
第九題
程式設計(滿分16分)
公司發了某商店的購物券1000元,限定隻能購買店中的m種商品。每種商品的價格分别為m1,m2,…,要求程式列出所有的正好能消費完該購物券的不同購物方法。
程式輸入:
第一行是一個整數m,代表可購買的商品的種類數。
接下來是m個整數,每個1行,分别代表這m種商品的單價。
程式輸出:
第一行是一個整數,表示共有多少種方案
第二行開始,每種方案占1行,表示對每種商品購買的數量,中間用空格分隔。
例如:
輸入:
2
200
300
則應輸出:
2
2 2
5 0
輸入:
2
500
800
則應輸出:
1
2 0
要求考生把所有函數寫在一個檔案中。調試好後,存入與考生檔案夾下對應題号的“解答.txt”中即可。相關的工程檔案不要拷入。
對于程式設計題目,要求選手給出的解答完全符合ANSI C标準,不能使用c++特性;不能使用諸如繪圖、中斷調用等硬體相關或作業系統相關的API。
遞歸思路,具體見代碼注解。
<span style="font-size:14px;">#include<stdio.h>
#include<string.h>
int m;//物品數
int p[100];//價格
int ans[100][100];//ans[i][j]表示第i個方案中第j個物品被選數
int num[100];//num[i]表示第i件物品被選的個數
int cas=0;//方案數
int money=0;//花的錢
void buy(int n)//n表示目前搜尋到的物品編号
{
if(money>1000||n>=m)//當花的錢超過預算或者所有的物品都已周遊過了,不再繼續搜尋下去
return ;
if(money==1000)//當花的錢正好為1000,滿足要求
{
for(int i=0; i<m; i++)
ans[cas][i]=num[i];
cas++;
return ;
}
num[n]++;//選該物品
money+=p[n];
buy(n);//可以繼續選該物品
num[n]--;//不選該物品,前面加的要減去
money-=p[n];//錢也相應的減
buy(n+1);//選下一個物品
}
int main()
{
scanf("%d",&m);
for(int i=0; i<m; i++)
scanf("%d",&p[i]);
memset(num,0,sizeof(num));
buy(0);
printf("%d\n",cas);
for(int i=0; i<cas; i++)
{
for(int j=0; j<m; j++)
printf("%d ",ans[i][j]);
printf("\n");
}
return 0;
}</span><span style="color:#ff0000;font-size: 18px;">
</span>
第十題
程式設計(滿分28分)
一種Playfair密碼變種加密方法如下:首先選擇一個密鑰單詞(稱為pair)(字母不重複,且都為小寫字母),然後與字母表中其他字母一起填入至一個5x5的方陣中,填入方法如下:
1.首先按行填入密鑰串。
2.緊接其後,按字母序按行填入不在密鑰串中的字母。
3.由于方陣中隻有25個位置,最後剩下的那個字母則不需變換。
如果密鑰為youandme,則該方陣如下:
y o u a n
d m e b c
f g h i j
k l p q r
s t v w x
在加密一對字母時,如am,在方陣中找到以這兩個字母為頂點的矩形(紅色字型):
y o u a n
d m e b c
f g h i j
k l p q r
s t v w x
這對字母的加密字母為該矩形的另一對頂點,如本例中為ob。
請設計程式,使用上述方法對輸入串進行加密,并輸出加密後的串。
另外有如下規定:
1、一對一對取字母,如果最後隻剩下一個字母,則不變換,直接放入加密串中;
2、如果一對字母中的兩個字母相同,則不變換,直接放入加密串中;
3、如果一對字母中有一個字母不在正方形中,則不變換,直接放入加密串中;
4、如果字母對出現在方陣中的同一行或同一列,如df或hi,則隻需簡單對調這兩個字母,即變換為fd或ih;
5、如果在正方形中能夠找到以字母對為頂點的矩形,假如字母對為am,則該矩形的另一對頂點字母中,與a同行的字母應在前面,在上例中應是ob;同樣若待變換的字母對為ta,則變換後的字母對應為wo;
6、本程式中輸入串均為小寫字母,并不含标點、空格或其它字元。
解密方法與加密相同,即對加密後的字元串再加密,将得到原始串。
要求輸入形式如下:
從控制台輸入兩行字元串,第一行為密鑰單詞(長度小于等于25),第二行為待加密字元串(長度小于等于50),兩行字元串末尾都有一個回車換行符,并且兩行字元串均為小寫字母,不含其它字元。
在标準輸出上輸出加密後的字元串。
例如,若輸入:
youandme
welcometohangzhou
則表示輸入的密鑰單詞為youandme,形成的正方形如上所示;待加密字元串為welcometohangzhou。在正方形中可以找到以第一對字母we為頂點的矩形,對應另一對頂點字母為vb,是以加密後為vb,同理可找到與字母對lc,et,oh,ho對應的頂點字母對。而字母對om位于上述正方形中的同一列,是以直接以颠倒這兩個字母來加密,即為mo,字母對an同理。字母對gz中的z不在上述正方形中,是以原樣放到加密串中。最後剩一個字母u也原樣輸出。
是以輸出的結果為:
vbrmmomvugnagzguu
要求考生把所有函數寫在一個檔案中。調試好後,存入與考生檔案夾下對應題号的“解答.txt”中即可。相關的工程檔案不要拷入。
對于程式設計題目,要求選手給出的解答完全符合ANSI C标準,不能使用c++特性;不能使用諸如繪圖、中斷調用等硬體相關或作業系統相關的API。
#include<stdio.h>
#include<string.h>
char a[5][5];
char s1[25],s2[25];
int l;
bool judge(char ch)//判斷該字元是否在密鑰字元串中
{
int sum=0;
for(int i=0; i<l; i++)
{
if(ch!=s1[i])
sum++;
}
if(sum==l)
return 1;
return 0;
}
bool judge2(char ch)//判斷該字元是否在密鑰矩陣中
{
int sum=0;
for(int i=0; i<5; i++)
{
for(int j=0; j<5; j++)
{
if(ch!=a[i][j])
sum++;
}
}
if(sum==25)
return 1;
return 0;
}
void posi(char ch,int &x,int &y)//該字元在密鑰矩陣中對應的坐标
{
for(int i=0; i<5; i++)
{
for(int j=0; j<5; j++)
{
if(a[i][j]==ch)
{
x=i;
y=j;
}
}
}
}
bool posijudge(char c1,char c2)//判斷兩字元是否在同一行或同一列
{
int x1,x2,y1,y2;
posi(c1,x1,y1);
posi(c2,x2,y2);
if(x1==x2||y1==y2)
return 1;
return 0;
}
int main()
{
scanf("%s%s",s1,s2);
l=strlen(s1);
int pos=0;
char ch='a';
for(int i=0; i<5; i++)//将密鑰字元串變為密鑰矩陣
{
for(int j=0; j<5; j++)
{
if(s1[pos]!='\0')
{
a[i][j]=s1[pos];
pos++;
}
else
{
while(!judge(ch))
{
ch++;
}
a[i][j]=ch;
ch++;
}
}
}
int n=strlen(s2);
char t1,t2;
char ans[25];
for(int i=0; i<n; i+=2)
{
t1=s2[i];
t2=s2[i+1];
if(t1==t2||t2=='\0')//情況1、2(對應規定1、2)
{
ans[i]=t1;
ans[i+1]=t2;
}
else if(judge2(t1)||judge2(t2))//情況3(對應規定3)
{
ans[i]=t1;
ans[i+1]=t2;
}
else if(posijudge(t1,t2))//情況4(對應規定4)
{
ans[i]=t2;
ans[i+1]=t1;
}
else//其它正常情況
{
int x1,x2,y1,y2;
posi(t1,x1,y1);
posi(t2,x2,y2);
ans[i]=a[x1][y2];
ans[i+1]=a[x2][y1];
}
}
printf("%s\n",ans);
return 0;
}