本文地址:http://www.cnblogs.com/CheeseZH/archive/2012/04/06/2435134.html
2011 模拟 c语言 本科
注意:
本套模拟题主要模拟命题形式与考核范围。真实竞赛题的数量、难度可能与此套模拟题有差异。
说明:
本试卷包含两种题型:“代码填空”与“程序设计”。
填空题要求参赛选手在弄清给定代码工作原理的基础上填写缺失的部分,使得程序逻辑正确、完整。所填写的代码不多于一条语句(即不能出现分号)。
编程题要求选手设计的程序对于给定的输入能给出正确的输出结果。注意:在评卷时使用的输入数据与试卷中给出的实例数据可能是不同的。选手的程序必须是通用的,不能只对试卷中给定的数据有效。
1. 代码填空(满分2分)
下列代码,把一个2位整数交换十位与个位的位置。请填写缺失的代码。
例如:当x=95时,返回59。
int switch_num(int x) { int a = x / 10; int b = x % 10; return b*10+a; }
2. 代码填空(满分3分)
下列代码把一个二进制的串转换为整数。请填写缺少的语句;
1 char* p = "1010110001100"; 2 int n = 0; 3 for(int i=0;i<strlen(p); i++) 4 { 5 n = n*2+p[i]-48; 6 } 7 printf("%d\n", n);
3. 代码填空(满分3分)
假设a,b,c是3个互不相等的整数。下列代码取出它们中居中的数值,记录在m中。其中的swap()函数可以交换两个变量的值。请完善代码。
1 if(a>b) swap(&a, &b); 2 if(b>c) swap(&b, &c); 3 if(a>b) swap(&a, &b); 4 int m = b;
4. 代码填空(满分5分)
计算3个A,2个B可以组成多少种排列的问题(如:AAABB, AABBA)是《组合数学》的研究领域。但有些情况下,也可以利用计算机计算速度快的特点通过巧妙的推理来解决问题。下列的程序计算了m个A,n个B可以组合成多少个不同排列的问题。请完善它。
int f(int m, int n) { if(m==0 || n==0) return 1; return f(m,n-1)+f(m-1,n); }
5. 代码填空(满分6分)
此段代码的意图是把一个缓冲区中的整数重新排列,使得所有负数都在正数的左边。请分析其工作流程,补充缺失的代码。
1 void reorder(int *pData, int len) 2 { 3 if(pData == NULL || len == 0) return; 4 int *pBegin = pData; 5 int *pEnd = pData+len-1; 6 while(pBegin < pEnd) 7 { 8 if(*pBegin<0) 9 { 10 pBegin ++; 11 continue; 12 } 13 if(*pEnd>=0) 14 { 15 pEnd --; 16 continue; 17 } 18 19 int temp = *pBegin; 20 *pBegin = *pEnd; 21 *pEnd = temp; 22 } 23 } 24 25 int main(int argc, char **argv) 26 { 27 int a[] = {1,2,3,-5,-4,5,9,-8,-1}; 28 reorder(a, 9); 29 30 for(int i=0; i<9; i++) printf("%d ", a[i]); 31 printf("\n"); 32 return 0; 33 }
6. 代码填空(满分9分)
给定一个字符串,其含有的字符各不相同。程序输出该字符串的所有排列(全排列)情形。例如:给定字符串“xyz”,则程序输出:
xyz
xzy
yxz
yzx
zyx
zxy
试完善程序中空缺的部分。
1 void f(char *str, int len, int n) 2 { 3 int i; 4 char tmp; 5 char *p = (char *)malloc(len+1); 6 if(n==len-1){ 7 printf("%s\n",str); 8 }else{ 9 for(i=n;i<len;i++){ 10 strcpy(p,str); 11 12 tmp = *(str+n); 13 *(str+n) = *(str+i); 14 *(str+i) = tmp; 15 16 f(str,len,n+1); 17 strcpy(str,p); 18 } 19 } 20 free(p); 21 } 22 23 int main(int argc, char **argv) 24 { 25 char str[] = "xyz"; 26 f(str,3,0); 27 printf("\n"); 28 return 0; 29 }
7. 代码设计(满分5分)
625这个数字很特别,625的平方等于390625,刚好其末3位是625本身。除了625,还有其它的3位数有这个特征吗?
请编写程序,寻找所有这样的3位数:它的平方的末3位是这个数字本身。
输出结果中,从小到大,每个找到的数字占一行。比如那个625就输出为:
625
#include <stdio.h> void main() { long i; for (i=100;i<=999;i++) if (i*i%1000 == i) printf("%ld\n",i); }
8. 代码设计(满分11分)
某游戏规则中,甲乙双方每个回合的战斗总是有一方胜利,一方失败。游戏规定:失败的一方要把自己的体力值的1/4加给胜利的一方。例如:如果双方体力值当前都是4,则经过一轮战斗后,双方的体力值会变为:5,3。
现在已知:双方开始时的体力值甲:1000,乙:2000。
假设战斗中,甲乙获胜的概率都是50%
求解:双方经过4个回合的战斗,体力值之差小于1000的理论概率。
1 #include <stdio.h> 2 #include <math.h> 3 int sum,r; 4 void f(int n,int a,int b) 5 { 6 if (n==0)//四局比完 7 { 8 if (abs(a-b)<1000) 9 r++;//符合条件的情况 10 sum++;//总的情况 11 return; 12 } 13 //a胜利 14 f(n-1,a+(b>>2),b-(b>>2)); 15 //b胜利 16 f(n-1,a-(a>>2),b+(a>>2)); 17 } 18 void main() 19 { 20 f(4,1000,2000); 21 printf("%.1lf%%\n",100.0*r/sum); 22 }
9. 代码设计(满分18分)
整数的分划问题。
如,对于正整数n=6,可以分划为:
6
5+1
4+2, 4+1+1
3+3, 3+2+1, 3+1+1+1
2+2+2, 2+2+1+1, 2+1+1+1+1
1+1+1+1+1+1+1
现在的问题是,对于给定的正整数n,编写算法打印所有划分。
用户从键盘输入 n (范围1~10)
程序输出该整数的所有划分。
1 #include <stdio.h> 2 int sln[11]; 3 int idx,N; 4 void output() 5 { 6 int i; 7 printf("%d",sln[0]); 8 for (i=1;i<idx;i++) 9 { 10 printf("+%d",sln[i]); 11 } 12 printf(","); 13 } 14 void f(int m,int n) 15 { 16 int i; 17 if (n<0 || m<n) 18 return; 19 if (n==0)//如果n=0,说明找完了。输出 20 { 21 output(); 22 return; 23 } 24 //如果m>=n&&n>=1,就从1查找到n。 25 for (i=n;i>=1;i--) 26 { 27 //首先把n放进去,并判断是否降序 28 sln[idx++]=i; 29 if(idx>1 && sln[idx-1]>sln[idx-2]) 30 { 31 idx--; 32 continue; 33 } 34 //再把n分解,n可以分解为1-n的数 35 f(m-i,m-i); 36 idx--; 37 if (m==N) 38 printf("\b \n"); 39 } 40 } 41 void main() 42 { 43 while (scanf("%d",&N)!=EOF) 44 { 45 idx = 0; 46 f(N,N); 47 } 48 }
10. 代码设计(满分20分)
一个N位的十进制正整数,如果它的每个位上的数字的N次方的和等于这个数本身,则称其为花朵数。
例如:
当N=3时,153就满足条件,因为 1^3 + 5^3 + 3^3 = 153,这样的数字也被称为水仙花数(其中,“^”表示乘方,5^3表示5的3次方,也就是立方)。
当N=4时,1634满足条件,因为 1^4 + 6^4 + 3^4 + 4^4 = 1634。
当N=5时,92727满足条件。
实际上,对N的每个取值,可能有多个数字满足条件。
程序的任务是:求N=21时,所有满足条件的花朵数。注意:这个整数有21位,它的各个位数字的21次方之和正好等于这个数本身。
如果满足条件的数字不只有一个,请从小到大输出所有符合条件的数字,每个数字占一行。因为这个数字很大,请注意解法时间上的可行性。要求程序在3分钟内运行完毕。
1 #include<stdio.h> 2 #include <string.h> 3 #include <time.h> 4 #define N 100000//虚拟进制 5 #define BN 5//exp21的容量需求 6 int exp21[10][BN]={//0-9的21次方 7 {00000,00000,00000,00000,00000}, 8 {00000,00000,00000,00000, 1}, 9 {00000,00000,00000, 20,97152}, 10 {00000,00000, 1, 4603,53203}, 11 {00000,00000, 439,80465,11104}, 12 {00000,00000,47683,71582, 3125}, 13 {00000, 21,93695, 6403,77856}, 14 {00000, 558,54586,40832,84007}, 15 {00000, 9223,37203,68547,75808}, 16 {00001, 9418,98913,15123,59209} 17 }; 18 int cm[10];//0-9被选的次数 19 int nm[10];//21位数中0-9出现的次数 20 int sum[BN];//累加和 21 int pass[1000][10];//已经出现过的 22 int sum_pass; 23 int check()//检查sum是否合法 24 { 25 if (sum[0]>9&&cm[0]!=21) return 0; 26 return 1; 27 } 28 void Add(int *a,int *b)//大数加法:a+=b 29 { 30 int i,carry=0; 31 for (i=BN-1;i>=0;i--) 32 { 33 a[i]=a[i]+b[i]+carry; 34 carry = 0; 35 if (a[i]>=N) 36 { 37 a[i]-=N; 38 carry = 1; 39 } 40 } 41 } 42 void Sub(int *a,int *b)//大数减法:a-=b 43 { 44 int i,borrow=0; 45 for (i=BN-1;i>=0;i--) 46 { 47 a[i]=a[i]-b[i]+borrow; 48 borrow = 0; 49 if (a[i]<0) 50 { 51 a[i]+=N; 52 borrow = -1; 53 } 54 } 55 } 56 int IsRight()//判断是否是花朵数 57 { 58 int i,j; 59 memset(nm,0,sizeof(nm)); 60 for (i=0;i<BN;i++)//统计sum中0-9的个数 61 { 62 j=sum[i]; 63 while (j) 64 { 65 nm[j%10]++; 66 j/=10; 67 } 68 } 69 for (i=0;i<10;i++) 70 if (cm[i]!=nm[i]) 71 return 0; 72 return 1; 73 } 74 void save()//将花朵数存储在pass数组中 75 { 76 int i; 77 pass[sum_pass][0]=sum[0]; 78 for (i=1;i<BN;i++) 79 pass[sum_pass][i]=sum[i]; 80 sum_pass++; 81 } 82 void sln(int n,int m)//用若干个m填充n个空 83 { 84 int i,j; 85 if (n==0) 86 return; 87 if (m==0) 88 { 89 cm[0]+=n; 90 if(IsRight()) 91 save(); 92 cm[0]-=n; 93 return; 94 } 95 for (i=n;i>=0;i--)//最多用n个,最少用0个 96 { 97 cm[m]+=i; 98 for (j=0;j<i;j++)Add(sum,exp21[m]);//sum加上i个exp21[m] 99 if (!check())//检查是否溢出 100 { 101 cm[m]-=i; 102 for (j=0;j<i;j++)Sub(sum,exp21[m]);//sum减去i个exp21[m] 103 continue; 104 } 105 if(n==1&&IsRight()) save(); 106 sln(n-i,m-1);//用若干m-1填补剩余的n-i个空 107 cm[m]-=i; 108 for (j=0;j<i;j++)Sub(sum,exp21[m]);//sum减去i个exp21[m] 109 } 110 } 111 void print()//输出结果、有点偷懒。。。 112 { 113 printf("%d%05d%05d%05d%05d\n",pass[1][0],pass[1][1],pass[1][2],pass[1][3],pass[1][4]); 114 printf("%d%05d%05d%05d%05d\n",pass[0][0],pass[0][1],pass[0][2],pass[0][3],pass[0][4]); 115 } 116 void main() 117 { 118 double b,e; 119 b = (double)clock(); 120 sln(21,9); 121 print(); 122 e = (double)clock(); 123 printf("程序执行时间:%.4fs\n",(e-b)/1000); 124 }