北理乐学C语言答案,最新

发布时间:2015-06-24 16:34:58   来源:文档文库   
字号:

7.入门 计算圆柱的侧面积及体积

#include

void main()

{

double a,b;

scanf("%lf\n%lf",&a,&b);

printf("s=%.2lf,v=%.2lf\n",2*3.14*a*b,3.14*a*a*b);

}

1. Hello world.

输入:

输出:Hello world.

程序:

#include

int main()

{

printf("Hello world.\n");

return 0;

}

2. Welcome to Beijing.

程序:

#include

int main()

{

printf("Welcome\n");

printf("to\n");

printf("Beijing.\n");

return 0;

}

3. A+B

输入:整数1 整数2

输出:整数1+整数2=

程序:

#include

int main()

{

int a,b;

scanf("%d",&a);

scanf("%d",&b);

printf("%d+%d=%d\n",a,b,a+b);

return 0;

}

4. x 3次方

输入:一个整数。

输出:该整数的 3 次方值。

程序:

#include

int main()

{

int x;

scanf("%d",&x);

printf("%d\n",x*x*x);

return 0;

}

5. 学习打印你的第一个图形

编写一个小程序,要求输出的是 4 行由*号组成的等腰三角形。

程序:

#include

int main()

{

printf(" *\n");

printf(" ***\n");

printf(" *****\n");

printf("*******\n");

return 0;

}

6. 一年级的算术题

输入: 接受两个整数,每个整数之间使用空格分隔。例如输入格式为:123 444

输出:分别输出按照整型数据进行 +-*/* 之后的运行结果。

程序:

#include

int main()

{

int a,b;

scanf("%d %d",&a,&b);

printf("%d+%d=%d\n",a,b,a+b);

printf("%d-%d=%d\n",a,b,a-b);

printf("%d*%d=%d\n",a,b,a*b);

printf("%d/%d=%d\n",a,b,a/b);

printf("%d%%%d=%d\n",a,b,a%b);

return 0;

}

7. 求两个变量的最小值

输入:两个整型数

输出:两个整型值中的最小值

程序:

#include

int main()

{

int a,b;

scanf("%d%d",&a,&b);

printf("min=%d\n",a

return 0;

}

8. 判断三角形的形状

输入:三角型的3条边的长度(int型)。

输出:等边三角形:equilateral triangle

等腰三角形:isoceles triangle

不构成三角形:non-triangle

一般三角形:triangle

程序:

#include

int main()

{

int a,b,c;

scanf("%d%d%d",&a,&b,&c);

if(a+b>c&&a+c>b&&b+c>a)

{

if (a==b&&b==c&&a==c)

printf("equilateral triangle.\n");

else if(a==b||a==c||b==c)

printf("isoceles triangle.\n");

else

printf("triangle.\n");

}

else

printf("non-triangle.\n");

return 0;

}

9. 计算圆柱的侧面积及体积

输入 第一行输入圆柱的底面半径 r

第二行输入圆柱的高 h

输出:s=< 圆柱的侧面积 >,v=< 圆柱的体积 >

要求

1. 所有变量都定义为双精度类型

2. 结果精确到小数点后两位

程序:

#include

#define PI 3.1415926

int main()

{

double r,h,s,v;

scanf("%lf",&r);

scanf("%lf",&h);

s=2*PI*r*h;

v=PI*r*r*h;

printf("s=%.2f,v=%.2f\n",s,v);

return 0;

}

10. 计算时钟的夹角

背景:

钟面上的时针和分针之间的夹角总是在 0 180之间 ( 包括 0 180 ) 。举例来说,在十二点的时候两针之间的夹角为 0 ,而在六点的时候夹角为180 ,在三点的时候为90 。本题要解决的是计算 12:00 11:59 之间任意一个时间的夹角。

输入:

每组测试数据包含两个数字:第一个数字代表小时 ( 大于 0 小于等于 12) ,第二个数字代表分 ( 在区间 [0, 59] )

输出:

对应每组测试数据,用常用格式显示时间以及这个时候时针和分针间的最小夹角,精确到小数点后一位。输出格式如下所示。

程序:

#include

#include

int main()

{

int h,m;

float d1,d2,d;

scanf("%d%d",&h,&m);

d1=30*(h+m/60.0);

d2=m*360/60.0;

d=fabs(d1-d2);

if(d>180)

d=360-d;

printf("At %d:%d the angle is %.1f degrees.\n",h,m,d);

return 0;

}

11. 找出最大素数

素数是指一个只能被1和它本身整除的数,在数论中占有重要的研究地位,在当代密码学中也被广泛应用。

输入:取值范围

输出:该范围内的最大素数

程序:

#include

int main()

{

int n,i,j;

scanf("%d",&n);

for(i=n;i>=1;i--)

{ for(j=2;j

if(i%j==0)

break;

if(j==i)

{

printf("The max prime number is %d.\n",i);

break;

}

}

}

12. 求最后3位数值

输入:a n 的值。假设 a<=150

输出: a n 次方的最后 3 位数。

程序:

#include

int main()

{

long int s=1;

int a,n,i=1,t=1;

scanf("%d%d",&a,&n);

if(n==0)

printf("The last 3 numbers is 1.\n");

else

{

for(i=1;i<=n;i++)

{

s=(s*a)%1000;

}

t=s%1000;

if(t>=0&&t<10) printf("The last 3 numbers is 00%d.\n",t);

if(t>=10&&t<100) printf("The last 3 numbers is 0%d.\n",t);

if(t>=100&&t<1000) printf("The last 3 numbers is %d.\n",t);

}

return 0;

}

13. 贪吃的猴子

有一只猴子,第一天摘了若干个桃子 ,当即吃了一半,但还觉得不过瘾 ,就又多吃了一个。第2天早上又将剩下的桃子吃掉一半,还是觉得不过瘾,就又多吃了两个。以后每天早上都吃了前一天剩下的一半加天数个(例如,第5天吃了前一天剩下的一般加5个)。到第n天早上再想吃的时候,就只剩下一个桃子了。

输入:天数n

输出:第一天的桃子个数

程序:

#include

int main()

{

int i,n,amount=1;

scanf("%d",&n);

for(i=n-1;i>=1;i--)

amount=2*(amount+i);

printf("The monkey got %d peachs in first day.\n",amount);

}

14. 黑色星期五

在西方,星期五和数字13都代表着坏运气,两个不幸的个体最后结合成超级不幸的一天。所以,不管哪个月的十三日又恰逢星期五就叫“黑色星期五”。

输入:年份

输出:判断该年是否包含黑色星期五,如包含,给出具体日期

程序:

#include

int main()

{

int i,n=0,year,month[12]={0};

int a[13]={0,13,44,73,104,134,165,195,226,257,287,318,348};

int b[13]={0,13,44,72,103,133,164,194,225,256,286,317,347};

scanf("%d",&year);

for(i=1;i<13;i++)

{

if ((year%4==0 && year%100!=0)||year%400==0)

{

if((year-1+((year-1)/4)-((year-1)/100)+((year-1)/400)+a[i])%7==5)

{

n++;

month[n]=i;

}

}

else

if((year-1+((year-1)/4)-((year-1)/100)+((year-1)/400)+b[i])%7==5)

{

n++;

month[n]=i;

}

}

if(n==1)

{

printf("There is %d Black Friday in year %d.\n",n,year);

printf("It is:\n");

printf("%d/%d/13\n",year,month[1]);

}

else

{

printf("There are %d Black Fridays in year %d.\n",n,year);

printf("They are:\n");

for (i=1;i<=n;i++)

{

printf("%d/%d/13\n",year,month[i]);

}

}

return 0;

}

15.你会输出一行星号?

我们才开始上机,现在需要我们用最简单得办法,在一行中输出N个星号。

输入:N

输出:一行中N个星号。

程序:

#include

int main()

{

int i,n;

scanf("%d",&n);

for(i=1;i<=n;i++)

printf("*");

printf("\n");

}

16. 计算SUM的值

已知公式:SUM = 1 + 1/2 + 1/3 + 1/4 + ... + 1/n

输入: n 输出: 表达式 sum 的值。结果保留 6 位小数。

程序:

#include

int main()

{

int i,n;

double sum=0;

scanf("%d",&n);

for (i=1;i<=n;i++)

sum+=1.0/i;

printf("sum=%.6lf\n",sum);

return 0;

}

17. 寻找特殊整数

请编写一个程序寻找一种特殊整数:一个 n 位的正整数等于其各位数字的n次方之和。例如:407=4×4×4+0×0×0+7×7×7。所以407就是一个特殊数。

输入:正整数的位数nn<=6)。

输出:

所有此n位特殊数。每个数占一行。若不存在符合条件的特殊数,则输出提示:“No output.”;若存在,则从小到大进行输出。

说明:

假设输入为4,在4位整数中,有34位的特殊数,则输出格式为(输出中的111122229999并不是4位特殊数,只是格式样例):

1111

2222

9999

程序:

#include

#include

int main()

{

int n,i,j,num,t,s=0,t1,flag=0;

scanf("%d",&n);

t=pow(10,n-1);

for (i=t;i

{

t1=i;

s=0;

for (j=1;t1!=0;j++)

{

num=t1%10;

s+=pow(num,n);

t1=t1/10;

}

if(s==i)

{

flag=1;

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

}

}

if(flag==0)

printf("No output.\n");

return 0;

}

18. 空心的倒三角型

输入:输入三角形的高度(h >= 0)。

输出:打印相应的空心倒三角形。图样参见测试用例。

程序:

#include

#include

int main()

{

int i,j,h;

scanf("%d",&h);

for (i=1;i<=h;i++)

{

for(j=1;j

printf(" ");

if(i==1||i==h)

{

for(j=1;j<=2*(h-i)+1;j++)

printf("*");

printf("\n");

}

else

{

printf("*");

for(j=1;j<=2*(h-i)-1;j++)

printf(" ");

printf("*\n");

}

}

return 0;

}

19. 空心字符菱形

输入:菱型起始字母和菱形的高度。

输出:参看测试用例,打印空心的由字符组成的菱形。

程序:

#include

#include

int main()

{

int i,j,h;

char ch;

scanf("%c%d",&ch,&h);

for (i=1;i<=h;i++)

{

for(j=1;j<=h-i;j++)

printf(" ");

printf("%c",ch+i-1);

for(j=1;j<=2*i-3;j++)

printf(" ");

if(i==1)

{

printf("\n");

continue;

}

printf("%c\n",ch+i-1);

}

for (i=h+1;i<=2*h-1;i++)

{

for(j=1;j<=i-h;j++)

printf(" ");

printf("%c",ch+(2*h-1)-i);

for(j=1;j<=(2*h-1-i)*2-1;j++)

printf(" ");

if(i==2*h-1)

{

printf("\n");

continue;

}

printf("%c\n",ch+(2*h-1)-i);

}

return 0;

}

20. 空心梯形

输入行数 n 和首数字字符,在屏幕上输出由数字围起的高和下底宽度均 n 的空心梯形。 要求:输出的数字是循环的,即输出数字 9 后再输出的数字是 0

输入:行数n 和首字符

输出:空心梯形

程序:

#include

#include

int main()

{

int i,j,n,f,t=0;

scanf("%d%d",&n,&f);

t=f;

for(j=1;j<=3*n-2;j++)

{

if(j==3*n-2)

printf("%d",t);

else

printf("%d ",t);

if(j<(3*n-1)/2)

{

if(t==9) t=0;

else

t++;

}

else if(j==(3*n-1)/2&&n%2==0) continue;

else

{

if(t==0) t=9;

else

t--;

}

}

printf("\n");

t=f;

for (i=2;i<=n;i++)

{

for (j=1;j<=2*(i-1);j++)

printf(" ");

if(i==n)

{

for (j=1;j<=(n+1)/2;j++)

{

if(t==9)

{

t=0;

printf("%d ",t);

}

else

printf("%d ",++t);

}

for (j=1;j<=n/2;j++)

{

if(t==0&&n%2!=0)

t=9;

else if(j==1&&n%2==0)

{

if(j==n/2)

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

else

printf("%d ",t);

continue;

}

else

t--;

if(j==n/2)

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

else

printf("%d ",t);

}

}

else

{

if(t==9)

{

printf("0");

for(j=1;j<=6*n-4*i-3;j++)

printf(" ");

printf("0\n");

t=0;

}

else

{

t++;

printf("%d",t);

for(j=1;j<=6*n-4*i-3;j++)

printf(" ");

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

}

}

}

return 0;

}

H1:计算通用产品代码(UPC)的校验位(选作)

下面是一种计算校验位的方法:首先把第一位、第三位、第五位、第七位、第九位和第十一位数字相加。然后把第二位、第四位、第六位、第八位和第十位数字相加。接着把第一次加法结果乘以3后再加上第二次加法的结果。随后,再把上述结果减去1。减法后的结果除以10取余数。最后,用9减去上一步骤中得到的余数。现在以Morton碘盐为例,第一组数字的加法是0+4+0+0+0+3=7,而第二组数字的加法是2+6+0+1+0=9。把第一组加法值乘以3后再加上第二组加法值得到的结果是30。再减去1,结果变为29。再把这个值除以10取余数为99在减去余数结果9,最终值为0

输入:每次输入三行数据,第一行是UPC的第一位数字,第二行是UPC的第一组五位数字,第三行是UPC的第二组五位数字。

输出:UPC的校验位

程序:

#include

#include

int main()

{

int i,j,s1=0,s2=0,t;

int a[11];

char b[6],c[6];

scanf("%d",&a[0]);

scanf("%s",b);

scanf("%s",c);

for (i=0,j=1;i<5;i++,j++)

a[j]=b[i]-48;

for (i=0,j=6;i<5;i++,j++)

a[j]=c[i]-48;

for (i=0;i<11;i++)

{

if(i%2==0)

s1+=a[i];

else

s2+=a[i];

}

t=9-(s1*3+s2-1)%10;

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

return 0;

}

H2:数制转换(选作)

这个题目会给你两个不同的数字,它们不属于同一进制,要求你计算出当它们分别处于何种进制之中时,两个数字相等。譬如 12 5 ,在十进制下它们是不等的,但若 12 使用 3 进制而 5 使用六进制或十进制时,它们的值就是相等的。因此只要选择合适的进制, 12 5 就可以是相等的。

程序的输入是两个数字 M N( 其十进制的值不超过 1000000000) ,它们的进制在 2~36 之间。对于十以下的数字,用 0~9 表示,而十以上的数字,则使用大写的 A~Z 表示。

求出分别在 2~36 哪种进制下 M N 相等。若相等则输出相应的进制,若不等则输出错误信息。当然了,对于多种可能成立的情况,找出符合要求的进制最小的一组就行了。信息的格式见测试用例。

程序:

#include

int main()

{

long int pm=0,pn=0,s=0,t=0,w=1,e=1,p=0,q=0;

int a[30],b[30];

char m[30],n[30];

int i,j,g,k,max1=0,max2=0,flag=0;

scanf("%s%s",m,n);

for(i=0;m[i]!='\0';i++)

{

if(m[i]>='A'&&m[i]<='Z')

a[i]=m[i]-55;

if(m[i]>='0'&&m[i]<='9')

a[i]=m[i]-48;

max1=max1<(a[i]+1)?(a[i]+1):max1;

max1=max1<2?2:max1;

}

pm=i;

for(j=0;n[j]!=0;j++)

{

if(n[j]>='A'&&n[j]<='Z')

b[j]=n[j]-55;

if(n[j]>='0'&&n[j]<='9')

b[j]=n[j]-48;

max2=max2<(b[j]+1)?(b[j]+1):max2;

max2=max2<2?2:max2;

}

pn=j;

for(i=max1,j=max2;i<=36&&j<=36; )

{

p=0;

q=0;

w=1;

e=1;

for(g=pm-1;g>=0;g--)

{

p+=a[g]*w;

w=w*i;

}

for(k=pn-1;k>=0;k--)

{

q+=b[k]*e;

e=e*j;

}

if(p

else if (p>q) j++;

else

{

flag=1;

printf("%s (base %d) = %s (base %d)\n",m,i,n,j);

break;

}

}

if(flag==0)

printf("%s is not equal to %s in any base 2..36\n",m,n);

return 0;

}

21. 零钱换整钱

小明手中有一堆硬币,小红手中有若干张10元的整钱。已知 1 角的硬币厚度为 1.8mm5 角的硬币厚 1.5mm 1 元的硬币为 2.0mm 。小明和小红一起玩游戏,小红拿出若干张10元的纸币,小明要将 1 角的硬币放成一摞,将 5 角的硬币硬币放成一摞,将 1 元的硬币放成一摞,如果 3 摞硬币一样高,并且金额能够正好小红要求的面值,则双方可以进行交换,否则没有办法交换。

输入:小红希望交换几张10元的纸币

输出:1 角的数量,5 角的数量,1元的数量

程序:三种硬币厚度公倍数:18mm110个共1元,512个共6元,19个共9元,要想3摞硬币一样高总钱数必须是16元(1+6+9)的公倍数)

#include

int main()

{

int n,t,x,y,z;

scanf("%d",&n);

t=n*10;

if(t%16!=0)

printf("No change.\n");

else

{

t=t/16;

x=t*10;

y=t*12;

z=t*9;

printf("%d,%d,%d\n",x,y,z);

}

return 0;

}

22. 买东西.

某商品有ABC三种品牌,各品牌的价格各不相同,其中A品牌的价格为每个5元, B品牌为每个3元,而C品牌为每31元。如果要用 M 元钱买 N 个该商品,要求每个商品至少买一个,编程求各种品牌各能买多少个。

输入:

先后输入M(钱数)及N(商品个数)的实际数值

输出:

所有可能情况下可以购买的3种商品的个数,按ABC品牌的顺序输出,用逗号分隔。例如:2,30,68;表示A品牌商品2个、B品牌商品30个、C品牌商品68个。

要求:因为有多个结果,结果的排序按照A品牌的个数从少到多的顺序输出。

程序:

#include

int main()

{

int i,j,k;

float m,n;

scanf("%f%f",&m,&n);

for(i=1;i

{

for(j=1;j<=n-1-i;j++)

{

for(k=1;k<=n-i-j;k++)

if((i*5+j*3+k*1.0/3)==m&&i+j+k==n)

printf("%d,%d,%d\n",i,j,k);

}

}

return 0;

}

23. 谁能出线

电视台举办超级学生才艺大赛,由于报名人数狂多,所以要先进行分组预赛。按规定,每10名学生为一个预赛小组,评委打出分数(0~100分),各小组第一名可以进入下一轮;如果有多名学生得分相同都是第一名,则可同时进入下一轮。

输入:

按顺序给出一个小组10个人的最后得分(int)。

输出:

能够出线的学生序号(0~9)。

程序:

#include

int main()

{

int i,s[10]={0},max=0;

for(i=0;i<10;i++)

{

scanf("%d",&s[i]);

if(max

max=s[i];

}

for(i=0;i<10;i++)

{

if(s[i]==max)

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

}

return 0;

}

24. 寻找特殊偶数

有一种特殊偶数,它每一位上的数字都两两不相同。我们现在需要找出四位数中某一区间内的这类偶数。

输入

所要寻找的四位偶数的范围。每组输入有两个数字:第一个数字是最小范围;第二个数字是最大范围。如果输入遇到0,输入结束。

输出

列出此范围内的所有特殊偶数,并且列出此范围内特殊偶数的个数。

程序:

#include

#include

main()

{

int i,j,k,a,b,c,d,m=0,e;

for(e=0;e>=0;e++)

{scanf("%d%d",&i,&j);

if((i==0)||(j==0)) break;

else if((i>9999||i<1000)||(j>9999||j<1000)) printf("Error\n");

else {for(k=i;k<=j;k++)

{if (k%2==1) continue;

a=k/1000;b=(k%1000)/100;c=(k%100)/10;d=k%10;

if((((a==b)||(b==c))||(c==d)) ||((d==a)||((a==c)||(d==b)))) continue;

printf("%d ",k);m+=1;}

printf("\ncounter=%d\n",m); m=0;}}

}

25.输出字母围起的正方形

输入N*N图形正方形的边长N,图形左上角的字母,输出由字母围成的空心正方形。输出的字母是顺时针连续的,且是循环的,即输出字母'Z'后输出字母"A"。注意在两个字母之间有一个空格。

程序:

#include

int main()

{

int n,i,j,t;

char m;

scanf("%d %c",&n,&m);

for(i=0;i

{

if(i==0)

{

for(j=0;j

{

t=m+j;

if((m<=90&&t>90)||(m>96&&t>122))

t=t-26;

if(j==n-1)

printf("%c\n",t);

else

printf("%c ",t);

}

}

else if(i==n-1)

{

for(j=0;j

{

t=m+3*n-3-j;

if((m<=90&&t>90)||(m>96&&t>122))

t=t-26;

if(j==n-1)

printf("%c\n",t);

else

printf("%c ",t);

}

}

else

{

for(j=0;j<2*n-1;j++)

{

if(j==0)

{

t=m+4*n-4-i;

if((m<=90&&t>90)||(m>96&&t>122))

t=t-26;

printf("%c",t);

}

else if(j==2*n-2)

{

t=m+n-1+i;

if((m<=90&&t>90)||(m>96&&t>122))

t=t-26;

printf("%c\n",t);

}

else

printf(" ");

}

}

}

return 0;

}

H3:猜数字(选作)

有如下一组数字,其中每个数字都在 1 ~ 63 之间,

1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63

2 3 6 7 10 11 14 15 18 19 22 23 26 27 30 31 34 35 38 39 42 43 46 47 50 51 54 55 58 59 62 63

4 5 6 7 12 13 14 15 20 21 22 23 28 29 30 31 36 37 38 39 44 45 46 47 52 53 54 55 60 61 62 63

8 9 10 11 12 13 14 15 24 25 26 27 28 29 30 31 40 41 42 43 44 45 46 47 56 57 58 59 60 61 62 63

16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63

32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63

现在需要编写一个程序,当从键盘输入某数字在且仅在哪几行出现了,该程序可以出这个数字是几。

输入:

程序的输入是一串以空白符分开的数字,当输入 0 时表示输入结束。

输出:

输出猜到的数字。

程序:

#include

int main()

{

int a[7],m,n=0,i,p=0;

for (i=0;i<7;i++)

{

scanf("%d",&a[i]);

n++;

if (a[i]==0)

{

break;

}

scanf(" ");

}

for (m=1;m<64;m++)

{

p=0;

for (i=0;i<(n-1);i++)

{

if (a[i]==1)

{

if (m==m/2*2)

{p=1;break;}

}

if (a[i]==2)

{

if (m%4!=3&&m%4!=2)

{p=1;break;}

}

if (a[i]==3)

{

if (m%8!=4&&m%8!=5&&m%8!=6&&m%8!=7)

{p=1;break;}

}

if (a[i]==4)

{

if(m%16!=8&&m%16!=9&&m%16!=10&&m%16!=11&&m%16!=12&&m%16!=13&&m%16!=14&&m%16!=15)

{p=1;break;}

}

if (a[i]==5)

{

if (m>31&&m<48||m<16)

{p=1;break;}

}

if (a[i]==6)

{

if (m<32)

{p=1;break;}

}

}

if (p==0)

{

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

break;

}

}

return 0;

}

H4:小蜜蜂(选作)

一只小蜜蜂在如下图所示的蜂窝上爬行。它爬行时,只能从一个格爬到相邻的大号格子中。例如,从 1 号格子可以爬到 2 号或者 3 号格子,从 2 号则可以爬到 3 号或者 4 号格子。

请问从一个格子 a 爬到一个格子 b 一共有多少种可行的路线。

输入:

分别是起始点 a 和终止点 b 的编号。( a b 1~100 之间,且 a。)

输出:

程序:

#include"stdio.h"

#define N 50

int main()

{

int b[N]={0};

int c[N]={0};

int i,j,k,n,a1,a2,t,l;

b[1]=c[1]=1;

scanf("%d%d",&a1,&a2);

n=a2-a1+1;

for(j=3;j<=n;j++)

{

for(i=1;i

{

t=b[i]+c[i];

if(l==1)

{

c[i]=b[i]-1;

l=0;

}

else

c[i]=b[i];

b[i]=t;

if(b[i]>=10)

{

l=1;

b[i+1]=b[i+1]+1;

b[i]=b[i]%10;

}

}

}

k=N;

while(b[--k]==0){}

for(i=k;i>=1;i--)

printf("%d",b[i]);

printf("\n");

return 0;

}

#include

int main()

{

long double num1,num2,num3=0;

int a=0,b=0,i;

scanf("%d %d",&a,&b);

num1=1;

num2=2;

if(b-a==1)

printf("1\n");

else if(b-a==2)

printf("2\n");

else

{

for(i=3;i<=b-a;i++)

{

num3=num1+num2;

num1=num2;

num2=num3;

}

printf("%.0lf\n",num3);

}

return 0;

}

H5.铺地板(选作)

背景:

你是一名室内装潢工程队的配料员。你的伙伴们喜欢采用字型的方式铺大理石地砖,图案如下:

1

2

6

7

15

3

5

8

14

16

4

9

13

17

22

10

12

18

21

23

11

19

20

24

25

学了 C 语言以后,你决定编写一个程序,帮助你的同伴生成这样的图形。

输入:

方阵N的大小。

输出

方阵。

程序:

#include

int main()

{

int i=0,j=0,g,n,t=1;

int a[100][100];

scanf("%d",&n);

for(g=0;g

{

if(g%2!=0)

{

for(i=0,j=g;i<=g&&j>=0;i++,j--)

{

a[i][j]=t;

t++;

}

}

else

{

for(i=g,j=0;i>=0&&j<=g;i--,j++)

{

a[i][j]=t;

t++;

}

}

}

for(g=1;g

{

if(g%2!=0)

{

for(i=g,j=n-1;i=g;i++,j--)

{

a[i][j]=t;

t++;

}

}

else

{

for(i=n-1,j=g;i>=g&&j

{

a[i][j]=t;

t++;

}

}

}

for(i=0;i

{

for(j=0;j

{

if(j==n-1)

printf("%2d",a[i][j]);

else

printf("%2d ",a[i][j]);

}

printf("\n");

}

return 0;

}

H6 晕(选作)

看着这样的形图案你晕吗?

让我们不用数组,来做出它。

输入:

n。正方形的边长

输出:

边长为 n 的数字回形方阵。

程序:

#include

int main()

{

int a[20][20],i,j,n,m=1,l,k=0;

scanf("%d",&n);

l=n;

for(i=1;i<=(n+1)/2;i++)

{

for(j=0;j

{a[k][j+k]=j+m;

a[n-1-k][j+k]=3*l-3+m-j;

}

for(j=1;j<=l-1;j++)

{a[j+k][k]=4*l-4-j+m;

a[j+k][n-1-k]=l+j+m-1;

}

m=m+4*l-4;

l=l-2;

k=k+1;

}

for(i=0;i<=n-1;i++)

{

for(j=0;j<=n-1;j++)

printf("%3d",a[i][j]);

printf("\n");

}

}

H7 子数整除(选作)

对于一个五位数a1a2a3a4a5,可将其拆分为三个子数:

sub1=a1a2a3

sub2=a2a3a4

sub3=a3a4a5

例如,五位数20207可以拆分成:

sub1=202

sub2=020=20

sub3=207

现在给定一个正整数K,要求你编程求出1000030000之间所有满足下述条件的五位数,条件是这些五位数的三个子数sub1sub2sub3都可被K整除。

输出时请按照由小到大的顺序排列(每行输出一个数)。

程序:

#include

int main(void)

{

int i,j,k,l,m,n;

scanf("%d",&n);

for (i=1;i<=3;i++)

for (j=0;j<=9;j++)

for (k=0;k<=9;k++)

for (l=0;l<=9;l++)

for (m=0;m<=9;m++)

{

if ((i*100+j*10+k)%n==0&&(j*100+k*10+l)%n==0&&(k*100+l*10+m)%n==0)

printf("%d%d%d%d%d\n",i,j,k,l,m);

if (i==3) return 0;

}

return 0;

}

H8 邮票组合(选作)

背景:

我们寄信都要贴邮票,在邮局有一些小面值的邮票,通过这些小面值邮票中的一张或几张的组合,可以满足不同邮件的不同的邮资。

现在,邮局有4种不同面值的邮票。在每个信封上最多能贴5张邮票,面值可相同,可不同。

输入:

四种邮票的面值。

输出:

用这四种面值组成的邮资最大的从1开始的一个连续的区间。

说明:

如结果为10,则表明使用4张邮票可组合出12345678910这些邮资。

名词解释:

邮资:就是你寄东西需要花多少钱。

邮票面额:是由国家发行的具有固定价格的花纸片,被称为邮票。

如果你寄东西,邮局称了重量,告诉你要240分。这样你就要贴邮票了。如果现在邮局的邮票有面值为80分、50分、20分和10分的四种,你就可以采用不同的组合得到240的邮资,例如:采用380分的可以凑出240分;或者2410分的凑起来240分也可以。显然不同邮票的组合都可以得到同样一种邮资。

程序:

#include

main()

{

int i,j,k,p,a1,a2,a3,a4,m=1,flag;

scanf("%d%d%d%d",&a1,&a2,&a3,&a4);

A: for(i=0;i<=5;i++)

{

for(j=0;j<=5-i;j++)

{

for(k=0;k<=5-i-j;k++)

{

for(p=0;p<=5-i-j-k;p++)

{

flag=1;

if(a1*p+a2*k+a3*j+a4*i==m)

{

flag=0;

m++;

goto A;

}

}

}

}

}

if(flag==1)

printf("The max is %d.\n",m-1);

}

H9 撞球(选做)

一天,丁俊晖编一整天的程序,突然觉得累了,于是便决定在房间内四处走走。他的房间是矩形的,他从电脑开始随便选了一个角度开始行走。由于职业习 惯,丁俊晖走路始终是直线,而且碰到墙以后会反弹,入射角度与出射角度完全相同。丁俊晖会一直行走,直到灵感再次迸发。假设他的行走速度是匀速的,现在, 丁俊晖的母亲想知道他一共休息了多长时间以便提醒他继续工作。

丁俊晖想考考他的母亲,于是他记录了自己碰到墙壁的序列并且告诉了她,你有没有办法能够帮助她计算出小丁所走的路程?

输入

输入包括多个测试用例,每个测试用例如下:

第一行包含两个数字 w, l(0,分别代表房间的宽度和长度;

第二行包括两个数字 x0, y0,代表电脑的位置坐标 (x0, y0)

第三行包含两个数字 x1, y1,代表丁俊晖的位置坐标 (x1, y1)

最后一行是一个包含'F', 'B', 'L', 'R'四种字符的字符串,分别代表墙在前面、后面、左边或是右边,字符串的长度小于等于 1000

我们约定,左上角的坐标为0,0,所有的坐标都是浮点型数字。

输出

一个浮点型数字,代表总路程,结果精确到小数点后 4 位。

程序:

#include"stdio.h"

#include"string.h"

#include"math.h"

void main()

{

char a[2000];

int w,l,x0,y0,x1,y1,i,k,r=0,f=0,n=0,m=0;

double c,d,s;

scanf("%d%d",&w,&l);

scanf("%d%d",&x0,&y0);

scanf("%d%d",&x1,&y1);

scanf("%s",a);

k=strlen(a);

for(i=0;i

{

if(a[i]=='R'||a[i]=='L')

m++;

if(a[i]=='F'||a[i]=='B')

n++;

}

for(i=0;i

{

if(a[i]=='R')

r=1;

if(a[i]=='L')

r=2;

if(r>0) break;

}

for(i=0;i

{

if(a[i]=='F')

f=1;

if(a[i]=='B')

f=2;

if(f>0) break;

}

if(m%2==0)

d=m*w+(x0-x1)*pow(-1,r);

else

d=m*w+w-x0-x1;

if(n%2==0)

c=n*l+(-y0+y1)*pow(-1,f);

else

c=n*l-l+y0+y1;

s=sqrt(pow(d,2)+pow(c,2));

printf("%.4f\n",s);

}

H10. 整数问题(选做)

请求输出满足以下条件的n位正整数的个数:

要求该n位整数的从高位开始前1位可以被1整除,该n位整数前2位可以被2*2整除,该整数前3位可以被3*3整除,该整数前4位可以被4*4整除……。即该整数前k位都可被k平方整除。

例如:n=1,则符合条件的1位正整数为19,输出答案9n=2,符合条件的正整数为:12, 16, 20, 24, 28, 32, 36, 40, 44, 48 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96,则输出答案22。当n=4时,2432就是一个符合题意的整数。第一位2可以被1整除;前224可以被4整除;前3243可以被9整除;整个42432可以被16整除。

输入:

  n(0<=n<9)

输出:

符合该条件的n位正整数的数量

(本题目为软件学院2007年保研学生初试上机试题。本题可以不用数组)

程序:

#include

#include

main()

{

static int a[30],b[30],n,t,temp,i,j,k;

scanf("%d",&n);

for(i=1;i<=n;i++)

{

t=1;

for(j=1;j<30;j++)

{

for(k=0;k<=9;k++)

{

b[t]=a[j]*10+k;

if(b[t]%(i*i)==0 && b[t]>b[t-1]) t++;

}

}

for(j=1;j<30;j++) {a[j]=b[j];b[j]=0;}

t--;

}

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

}

26.二年级小学生的题目

两个二年级小朋友在一起玩游戏,小明给出一堆不超过两位的正整数和运算要求(+-*/%),小丽要找出这些整数中的最大值和最小值,然后按照小明的要求算出最大数与最小数进行算术运算的结果。

输入:

用逗号分隔的不超过两位的正整数序列,及其运算符和等号

输出:

最大数 op 最小数=结果

程序:

#include

int main()

{

int i,a,max=0,min=100,s;

char l[100]={0},op;

gets(l);

for(i=0;;i=i+2)

{if(l[i]=='=') break;

else

{if(l[i]==43||l[i]==45||l[i]==42||l[i]==37||l[i]==47)

op=l[i];

else

{if(l[i+2]==44)

{a=(l[i]-48)*10+l[i+1]-48;

i++;

}

else a=l[i]-48;

if(a>=max)

{max=a;}

if(a<=min)

{min=a;}

}

}}

switch(op)

{case 43:s=max+min;printf("%d + %d = %d\n",max,min,s);break;

case 45:s=max-min;printf("%d - %d = %d\n",max,min,s);break;

case 42:s=max*min;printf("%d * %d = %d\n",max,min,s);break;

case 37:{if(min==0) {printf("Error!\n");break;}

else {s=max%min;

printf("%d % %d = %d\n",max,min,s);

break;}

}

case 47:{if(min==0) {printf("Error!\n");break;}

else {s=max/min;

printf("%d / %d = %d\n",max,min,s);

break;}

}

}

}

27.等值数列段

如果一个数列中的某一段(至少有两个元素)的各元素值均相同,则称之为等值数列段。等值数列段中元素的个数叫做等值数列段的长度。

输入:

N个元素组成的整数数列A(其中N<=50)

输出:

A中长度最大的所有等值数列段的始末位置,如果没有等值数列段,则输出No equal number list.

说明:

始末位置是指数组下标,即0表示第一个元素。

如果有多个同等长度的等值数列,只输出第一个等值数列的起始位置。

当在一个LIST中出现两个等长的连续串的时候,我们的答案应该是第一个等长串。

程序:

#include

#include

#define N 50

#define M 50

int main()

{

char a[N],t;

int i,j=0,n,b[M]={0},max=0,min=0,temp;

scanf("%d",&n);

k:

{

gets(a);

if((strlen(a)+1)/2!=n)

goto k;

}

t=a[0];

b[0]=0;

for(i=2;i

{

if(t!=a[i])

{

t=a[i];

j++;

b[j]=(i+1)/2;

}

}

j++;

b[j]=(i+1)/2;

temp=b[1]-b[0];

max=b[1]-1;

min=b[0];

for(i=1;i<=j;i++)

{

if(temp

{

temp=b[i+1]-b[i];

max=b[i+1]-1;

min=b[i];

}

}

if(temp==1)

printf("No equal number list.\n");

else

printf("The longest equal number list is from %d to %d.\n",min,max);

return 0;

}

28.大家一起做游戏

输入:

小朋友的个数(<=50 要被练习的数字

输出:

最终被留下的小朋友的序号

说明:

要被练习的数字5,则每次数到5的同学要退出该游戏

程序:

#include

void main()

{

long int left,p,i,j,k,q,flag[100],n,m;

scanf("%d%d",&n,&m);

left=n; p=1;

for (i=1;i<=n;i++) flag[i]=1;

for (i=1;i<=n;i++)

{

q=(m-1)%left+1;

j=0; k=p;

while (j!=q)

{

if (flag[k]==1) j++;

if (j==q) break;

k++; if (k==n+1) k=1;

}

flag[k]=0;

p=k; left--;

}

printf("The left child is NO %d.\n",k);

}

29. 组成最大数

任意输入一个自然数,输出该自然数的各位数字组成的最大数。例如,输入 1593 ,则输出为 9531

输入: 自然数 n

输出: 各位数字组成的最大数

程序:

#include

#include

int main()

{

char a[10000];

int x[10]={0};

scanf("%s",a);

int n=strlen(a);

for(int i=0;i

x[a[i]-'0']++;

for(int i=9;i>=0;i--)

for(int j=0;j

printf("%d",i);

printf("\n");

}

30. 删除重复字符

背景:

输入一个长度不超过 100 的字符串,删除串中的重复字符。

输入:

输入要检查的字符串,长度不超过100个字符。例如:abacaeedabcdcd

输出:

删除重复字符后的字符串。例如:abced

程序:

#include

#include

#define N 100

int main()

{

char a[N],t;

int i,j,k;

scanf("%s",a);

for(i=0;i

{

for(j=i+1;j

{

if(a[i]==a[j])

{

for(k=j;k

a[k]=a[k+1];

j--;

}

}

}

printf("%s\n",a);

return 0;

}

H11:五年级小学生的题目(选做)

那两个小朋友在不断进步,他们已经学会了负数和多位数,于是他们又开始进行游戏了。小明给出一堆整数和运算要求(+-*/%),小丽要找出这些整数中的最大值和最小值,然后按照小明的要求算出最大数与最小数进行算术运算的结果。

输入:

用逗号分隔的整数序列,及其运算符和等号

输出:

最大数 op 最小数=结果

说明:本题目应该可以不使用数组就可以完成,关键是如何处理负数和减法

程序:

#include

#include

int intpow(int a,int b)//a^b

{

int result=1;

for(int i=0;i

result=result*a;

return result;

}

struct date

{

int max;

int min;

char op;

int r;

};

struct date function(char p[],int n)

{

struct date result;

n=n-4;

int max=-10000;

int min=10000;

int count=0;//need back to 0

int x[10]={0};//need back to 0

int temp=0;//need back to 0

int sign=1;//need back to 1

for(int i=0;i<=n;i++)

{

if (p[i]==',')//meet , means end caculate the value and compare with max and min

{

for(int k=0;k

temp=temp+x[k]*intpow(10,count-1-k);

temp=temp*sign;

if(temp>max) max=temp;

if(temp

count=0;temp=0;sign=1;

continue;

}

if(p[i]=='-')

{

sign=-1;

continue;

}

else

{

x[count]=p[i]-'0';

count++;

}

}

char opp;

opp=p[n+1];

if(opp=='+')

{result.r=max+min;result.op='+';}

else if(opp=='-')

{result.r=max-min;result.op='-';}

else if(opp=='*')

{result.r=max*min;result.op='*';}

else if(opp=='/')

{

if(min==0)

result.r=0;

else

{

result.r=max/min;

}

result.op='/';

}

else if(opp=='%')

{result.r=max%min;result.op='%';}

result.max=max;

result.min=min;

return result;

}

int main()

{

char w[100];

gets(w);

int l=strlen(w);

struct date cc=function(w,l);

if(cc.op=='/'&&cc.min==0)

printf("Error!");

else

{

if(cc.max<0)

printf("(%d)",cc.max);

else

printf("%d",cc.max);

printf(" %c ",cc.op);

if(cc.min<0)

printf("(%d)",cc.min);

else

printf("%d",cc.min);

printf(" = ");

printf("%d",cc.r);

printf("\n");

}

}

H12:扫雷(选做)

输入

输入中将包括一系列的地图,每个地图的第一行有两个整数 n m0 ),它们表示了地图的行数和列数。下面的 n 行每行都有 m 个字符,其中 "." 表示安全而 "*" 表示地雷。如果地图的 n m 都为 0,则表示输入结束。

输出

针对每一个地图,首先输出一行:

Field #x:其中 x 是当前地图的编号(从 1 开始)。下面的 n 行则将地图中的 "." 以数字表示,该数字表示该方格周围有多少颗地雷。

程序:

#include

#define N 110

void main()

{

char a[N][N];

int n,m,t,i,j,k=1;

static int b[N][N];

for(n=m=1; n!=0 && m!=0; )

{

for(i=0;i

{

for(j=0;j

b[i][j]=0;

}

scanf("%d %d",&n,&m);

for(t=n;t>0;t--)

scanf("%s",a[n-t]);

for(i=0;i

{

for(j=0;j

{

if(a[i][j]=='*')

{

b[i][j]++;b[i+1][j]++;b[i+2][j]++;b[i][j+1]++;b[i+2][j+1]++;b[i][j+2]++;b[i+1][j+2]++;b[i+2][j+2]++;

}

}

}

if(n!=0&&k>1) {printf("\nField #%d:\n",k); k++;}

else if(n!=0) {printf("Field #%d:\n",k); k++;}

for(i=0;i

{

for(j=0;j

{

if(a[i][j]=='*') printf("*");

else printf("%d",b[i+1][j+1]);

}

}

}

}

31.合并字符串

输入两个已经按从小到大顺序排列好的字符串,编写一个合并两个字符串的函数,使合并后的字符串,仍然是从小到 大排列。

输入:

两个已经排好顺序(升序)的两个字符串

输出:

一个合并在一起的有序(升序)的字符串

要求:

设计一个效率尽量高的算法,对每个字符串只扫描一遍就可以了。

如果采用先进行串连接,然后再进行排序的算法,则效率太低了。

程序:

#include

int main()

{ char a[100],b[100],c[200];

int i=0,j=0,k=0;

gets(a);gets(b);

while(i

{

if(a[i]

{

c[k++]=a[i++];

}

else

{

c[k++]=b[j++];

}

}

while(i

{

c[k++]=a[i++];

}

while(j

{

c[k++]=b[j++];

}

c[k]='\0';

printf("%s\n",c);

return 0;

}

32. 串的减法

输入字符串st(串长不超过80个字符),将在字符串s中出现,但未在字符串t中出现的字符组成一个新的字符串放在u中,u中字符按原字符串中字符顺序排列,不去掉重复字符,输出u

例如:当s="112345"t="2467"时,u="1135"

输入:

  第一行为串s

  第二行为串t

输出:

u

程序:

#include

#include

main()

{

char s[800],t[800];

static int a[500]={0};

int i,k,m,n;

gets(s);

gets(t);

m=strlen(s);

n=strlen(t);

for(i=0;i<=n-1;i++)

{

k=t[i];

a[k]=1;

}

for(i=0;i<=m-1;i++)

{

k=s[i];

if(a[k]==0)

printf("%c",s[i]);

}

printf("\n");

return 0;

}

33.单词排序

输入 5 个单词,将它们按从大到小的顺序排列后输出。

输入:

5个单词

输出:

排序后的顺序

程序:

#include

#include

main()

{

char a[5][25],b[5][25];

int i,j,k;

for(i=0;i<5;i++)

scanf("%s",&a[i]);

for(i=0;i<5;i++)

{

for(k=0,j=0;j<5;j++)

if(strcmp(a[i],a[j])<0)k++;

strcpy(b[k],a[i]);

}

for(i=0;i<5;i++)

printf("%s\n",b[i]);

}

34.北理工的恶龙

背景:

最近,北理工出现了一只恶龙,它长着很多头,而且还会吐火,它将会把北理工烧成废墟, 于是,校长下令召集全校所有勇士杀死这只恶龙。要杀死这只龙,必须把它所有的头都砍掉,每个勇士只能砍一个龙头,龙的每个头大小都不一样,一个勇士只有在身高不小于龙头的直径的情况下才能砍下它。而且勇士们要求,砍下一个龙头必须得到和自己身高厘米数一样的学分。校长想花 最少的学分数杀死恶龙,于是找到你寻求帮助。

输入:

第一行 龙头数 n , 勇士人数 m 1<=n, m<=100 接下来 n 行,每行包含一个整数,表示龙头的直径 接下来 m 行,每行包含一个整数,表示勇士的身高 l

输出:

如果勇士们能完成任务,输出校长需要花的最小费用;否则输 “ bit is doomed! ”

程序:

#include

int main()

{

int n,m,i,j,t,k,c,d;

scanf("%d%d",&n,&m);

int a[100]={0}; int b[100]={0};

for(i=0;i

scanf("%d",&a[i]);

for(j=0;j

scanf("%d",&b[j]);

for(i=0;i

{

for(j=0;j

{

if(a[j]>a[j+1])

{

t=a[j];

a[j]=a[j+1];

a[j+1]=t;

}

}

}

for(i=0;i

{

for(j=0;j

{

if(b[j]>b[j+1])

{

t=b[j];

b[j]=b[j+1];

b[j+1]=t;

}

}

}

k=0;

for(i=0;i

{

for(j=k;j

{

if(b[j]>=a[i])

{

a[i]=0; k++; break;

}

else

{

b[j]=0; k++;

}

}

if (k>m) break;

}

for(i=k;i

b[i]=0;

c=0;d=0;

for(i=0;i

c=c+a[i];

for(i=0;i

d=d+b[i];

if(c==0)

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

else

printf("bit is doomed!\n");

}

35.杀鸡用牛刀——要用递归啊!

背景:

哈哈!我们终于学了递归了,现在大家一定感到非常有意思吧,那个典型的汉诺塔问题,一个非常短的程序居然可以完成如此复杂的工作,真是神奇啊!来吧,让我们也动手编写一个递归程序,当然,我们要编写的不可能太复杂。

功能:

求整数 n m 区间的累加和,其中n<=m

输入:

区间的起始点n 区间的终止点m

输出:

累加和

要求:

使用递归算法完成。如此简单的题目当然要有隐含的测试用例啦,就3个,看看谁能猜出来。

程序:

#include

void main()

{

int sum( int n, int m );

int n, m;

scanf( "%d %d", &n, &m );

printf( "The sum from %d to %d is %d.\n", n, m, sum( n, m ) );

}

int sum( int n, int m )

{

int s;

if ( m==n ) s=n;

else s=m+sum( n, m-1 );

return ( s );

}

H13:安全的密码(选做)

随着电子设备的广泛运用,密码也渐渐融入每个人的生活。保护好密码,不仅关系到个人隐私,更关系到个人的财产和安全。一个安全的密码,最好由大小写字母、数字或符号组成。包含越多种类的字符,其安全性就越高。同时密码还需要有一定的长度,通常至少要由六个以上的字符组成。

并不是每个人都喜欢这样复杂的密码,很多人在设置密码的时候,喜欢使用自己的名字或者生日,但这是很大的安全隐患。

任务

林晓炜正在设计一个网络交易系统,为了保证用户的密码安全,他需要一个程序,判断用户自己设置的密码是否安全,如果不安全,则给出提示。现在他向你求助,请你帮忙设计一个程序来解决这个问题。

应当按照以下的规则来判断密码是否安全:

如果密码长度小于 6 位,则不安全

如果组成密码的字符只有一类,则不安全

如果组成密码的字符有两类,则为中度安全

如果组成密码的字符有三类或以上,则为安全

通常,可以认为数字、大写字母、小写字母和其它符号为四类不同的字符。

输入

输入的第一行是一个整数 N,表明后面有多少组密码。随后的 N 行输入包括 N 个密码,每个密码的长度均小于 20 个字符。

输出

针对每一个密码判断并输出它是否安全。对于不安全的密码输出 "Not Safe",对于中度安全的密码输出 "Medium Safe",对于安全的密码输出 "Safe"

输入样例

4

1234

Abcdef

ABC123

1#c3Gh

输出样例

Not Safe

Not Safe

Medium

Safe

Safe

程序:

#include

#include

int main(void)

{

int n,i,j,x,m,b[4];

char a[100];

scanf("%d",&n);

for (i=1;i<=n;i++)

{

gets(a);

if (i==1) gets(a);

x=strlen(a);

if (x<6) {printf("Not Safe\n");continue;}

b[0]=0;b[1]=0;b[2]=0;b[3]=0;

for (j=0;j<=x-1;j++)

{

if (48<=a[j]&&a[j]<=57) b[0]=1;

else

if (65<=a[j]&&a[j]<=91) b[1]=1;

else

if (97<=a[j]&&a[j]<=123) b[2]=1;

else b[3]=1;

if (a[0]+a[1]+a[2]+a[3]==4) break;

}

m=b[0]+b[1]+b[2]+b[3];

switch (m)

{

case 1:printf("Not Safe\n");break;

case 2:printf("Medium Safe\n");break;

case 3:printf("Safe\n");break;

case 4:printf("Safe\n");

}

}

return 0;

}

H14:身份证的奥秘(选做)

输入

输入n组身份证号码,第一行为个数,以后每行为身份证号码。

输出

如果输入的身份证号码为15位,则将其升级为18位后显示输出;否则判断其是否为合法身份证号,并逐行输出。

程序:

#include

#include

char ans(char x[20])

{

int i,y;

int d[20]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2,0,0,0};

char e[11]={'1','0','X','9','8','7','6','5','4','3','2'};

y=0;

for (i=0;i<=16;i++) {y=y+(x[i]-48)*d[i];y=y%11;}

y=y%11;

return e[y];

}

int main(void)

{

int i,n,m,j;

char a[1000],b[20];

scanf("%d",&m);

for (i=1;i<=m;i++)

{

scanf("%s",&a);

n=strlen(a);

if ((n!=15)&&(n!=18)) {printf("Invalid\n");continue;}

if (n==15)

{

for (j=0;j<=5;j++) b[j]=a[j];

if (a[12]=='9'&&a[13]=='9'&&(a[14]=='6'||a[14]=='7'||a[14]=='8'||a[14]=='9'))

{b[6]='1';b[7]='8';}

else {b[6]='1';b[7]='9';}

for (j=8;j<=16;j++) b[j]=a[j-2];

b[17]=ans(b);

b[18]='\0';

printf("%s\n",b);

}

else if (a[17]==ans(a)) printf("Valid\n"); else printf("Invalid\n");

}

return 0;

}

36.科学记数法

对于非常大或者非常小的数据,我们通常用科学记数法来表示。例如在科技文献和电脑中经常遇到的 2.3×106 (计算机中的科学记数法表示为:2.3E6),或者 9.18×10-5 (科学记树法表示:9.18E-5)这种类型的数据。

输入:

用科学记数法表示的数据。即为符合C语言表示的科学记数法表示。

输出:

该数据的双精度表示

说明:

输入数据的精度不高于小数点后50位。

输入数据时,在实数和幂之间有空格进行分隔,空格个数不定。

结果保留到小数点后8位,如不足8位用0补足,超过8位则截断,不进行四舍五入的处理。

程序:

#include

#include

#define N 100

void main()

{

char a[N],b[N];

int i,j,s,q,x;

gets(a);

x=strlen(a);

for( s=0,q=1,x-- ; '0'<=a[x] && a[x]<='9' ; x--, q*=10 )

s=s+(a[x]-'0')*q;

if( a[x]=='-' )

s=-s;

for( i=j=0; a[i]!=' '; i++ )

{

if( a[i]<='9' && a[i]>='0' )

{

b[j]=a[i];

j++;

}

}

if(s<=0)

{

for( i=s; i<=s+8; i++)

{

if(i<0) printf("0");

if(i>=0&&i

if(i==s) printf(".");

if(i>=j) printf("0");

}

printf("\n");

}

if(s>0)

{

for( i=0; i<=s+8; i++ )

{

if(i

if(i>=j) printf("0");

if(i==s) printf(".");

}

printf("\n");

}

}

37.大数分解

从键盘输入的一个大于 1 的整数,通过算法将该整数分解为若干因子的乘积。

输入:

一个正整数。

输出:

分解后的各个因子。

程序:

#include

#include

int su(int shu)

{

int i=0;

for(i=2;i<=sqrt(shu);i++)

if(shu%i==0)

return (1);

else

continue;

return (0);

}

int main()

{

int shu,i=0;

int a[16]={2,3,5,7,11,13,17,19,23,29,31,34,37,41,43,47};

scanf("%d",&shu);

loop: if(su(shu)==0)

{

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

return 0;

}

else

{

for(i=0;i<16;)

{

if(shu%a[i]==0)

{

printf("%d\n",a[i]);

shu/=a[i];

goto loop;

}

else if(shu%a[i]!=0)

{

i++;

continue;

}

else if(shu==1)

break;

}

}

return 0;

}

38.回文字符串——递归

有一种特殊形式的字符串,其正反序相同,被称为“回文字符串”。例如LeveL就是一个回文字符串。

输入:

字符串

输出:

Yes或者No

说明:

如输出Yes,说明输入的字符串是一个回文字符串

输出No,说明输入的字符串不是一个回文字符串

请使用递归算法实现。

程序:

#include

#include

char str[1000];

int HUI(char str[],int min,int max)

{

if(min>max)

return 1;

if(str[min]!=str[max])

return 0;

return HUI(str,min+1,max-1);

}

void main()

{

int flog,max;

gets(str);

max=strlen(str)-1;

flog=HUI(str,0,max);

if(flog==1)

printf("Yes\n");

else

printf("No\n");

}

39.求最大公约数——递归

输入:

nm

输出:

nm的最大公约数

程序:

#include

#include

int GCD(int m,int n)

{

int s,t;

s=m%n;

if(s==0)

t=n;

else

t=GCD(n,s);

return t;

}

int main()

{

int m,n;

scanf("%d%d",&m,&n);

printf("%d\n",GCD(m,n));

return 0;

}

40.求序列之和——递归

请使用递归算法求下列序列的前n项之和。

1 + 1/2 - 1/3 + 1/4 -1/5 ......

输入:

n

输出:

序列的前n项和(精确到小数点之后第6位)

程序:

#include

float sum(int n)

{

float s1;

if(n==1)

return 1.0;

if(n%2==0)

s1=sum(n-1)+1.0/n;

else

s1=sum(n-1)-1.0/n;

return s1;

}

int main()

{

int n;

float s=0;

scanf("%d",&n);

s=sum(n);

if(n==1)

printf("1\n");

else

printf("%.6f\n",s);

}

H15:编码问题(选作)

设有一个整形数组 A[0..N-1];存放的元素为 0N-1 (1之间的整数,且 A[i]A[j]ij)。例如,当N=6时,有:A=430512)。此时,数组A的编码定义如下:

A[0]编码为0

A[i]编码为:在A[0]A[1],…,A[i-1]中比A[i]的值小的个数 i=12,…,N-1

例如上面数组 A的编码为:B=000312

若给出数组A,则可求出其编码。同理,若给出数组A的编码,可求出A中的原数据。

输入:

推导方向(取值为12,如为1,则表示根据数组求数组编码;如为2,则表示根据编码反求数组)

数组个数

数组或数组编码元素

输出:

数组编码、或数组本身(元素之间以空格分隔)

程序:

#include

#define N 100

void main()

{

int mode,n,i,j,s,a[N],b[N];

static int c[N];

scanf("%d",&mode);

scanf("%d",&n);

for( i=0; i

scanf("%d", &a[i]);

if(mode==1)

{

for( i=1,b[0]=0; i

for( j=0,b[i]=0; j

if( a[i]>a[j]) b[i]++;

}

else

{

for( i=n-1; i>=0; i-- )

{

for( j=0,s=0; s

if (c[j]==0) s++;

b[i]=j-1;

c[b[i]]=1;

}

}

for( i=0; i

printf("%d\n",b[n-1]);

}

H16:洗牌(选作)

假设我们有 2n 张牌,它们以 1, 2, ..., n, n+1, ..., 2n 编号并在开始时保持着这种顺序。一次洗牌就是将牌原来的次序变为 n+1, 1, n+2, 2, ..., 2n, n,也就是将原来的前 n 张牌放到位置 2, 4, ..., 2n,并且将余下的 n 张牌按照他们原来的次序放到奇数位置 1, 3, ..., 2n-1。已经证明对于任何一个自然数 n,这 2n 张牌经过一定次数的洗牌就回到原来的次序。但我们不知道对于一个特定的 n,需要几次洗牌才能将牌洗回原来的次序。

输入:

牌张数的一半n,即初始情况下一共有2n张牌,nint型整数

输出:

将牌洗回原来的次序所需要的洗牌次数

程序:

#include

int main(void)

{

int n,x,total;

total=1;

scanf("%d",&n);

x=2;

while (x!=1)

{

if (x<=n) x=x*2;

else x=2*(x-n)-1;

total=total+1;

}

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

return 0;

}

41.输出字符回形阵

输入图形行数N和中心字符,输出如图所示回形方阵。

例如,输入:5 Z

输出如下图形:

X X X X X

X Y Y Y X

X Y Z Y X

X Y Y Y X

X X X X X

注:N<24,且N是奇数。

程序:

#include

int main()

{

char ch, a[1000][1000]={0};

int i,j,k,n,mid;

scanf("%d %c",&n,&ch);

if(n%2==0)

printf("%d is not a odd number!\n",n);

else

{

mid=(n-1)/2;

a[mid][mid]=ch;

if(ch>='a'&&ch<='z')

{

for(k=1;k<=mid;k++)

{

for(i=mid-k;i<=mid+k;i++)

for(j=mid-k;j<=mid+k;j++)

{

if (i==mid-k||i==mid+k)

a[i][j]=ch-k+(26*(k>(ch-'a')?1:0));

else if (j==mid-k||j==mid+k)

a[i][j]=ch-k+(26*(k>(ch-'a')?1:0));

}

}

}

else if(ch>='A'&&ch<='Z')

{

for(k=1;k<=mid;k++)

{

for(i=mid-k;i<=mid+k;i++)

for(j=mid-k;j<=mid+k;j++)

{

if (i==mid-k||i==mid+k)

a[i][j]=ch-k+(26*(k>(ch-'A')?1:0));

else if (j==mid-k||j==mid+k)

a[i][j]=ch-k+(26*(k>(ch-'A')?1:0));

}

}

}

for (i=0;i

for(j=0;j

{

if(j==n-1)

printf("%c\n",a[i][j]);

else

printf("%c ",a[i][j]);

}

}

}

42.子串反向——递归

请编写一个递归函数 reverse(char str[], int start, int end ) ,该函数的功能是将串 str 中下标从 start 开始到 end 结束的字符颠倒顺序。假设 start end 都在合理的取值范围。

例如:

执行前:str[]="0123456"start=1 end=4

执行后:strr[]="0432156"

要求在该函数中不使用新的数组,没有循环。

注意:只需要编写递归函数 reverse,系统中已经设置好了main函数。

预设代码

前置代码

1. #include

2. int main( )

3. { char str[100];

4. int start, end;

5. gets(str);

6. scanf("%d%d", &start, &end);

7. reverse( str, start, end );

8. printf("%s\n", str);

9. return 0;

10. }

11.

程序:

#include

void reverse(char str[],int start,int end)

{

char t;

if (end>=strlen(str)) reverse (str,start,end-1);

else if (start

{

reverse (str,start+1,end-1);

t=str[start];

str[start]=str[end];

str[end]=t;

}

}

H17:高精度加减法(选作)

背景:

计算机所能完成的一个基本功能就是完成数据的计算,譬如加法、减法等等。但是在任何一种计算机上,计算中能够使用的数字都是有一定范围的,超过了范围,就没法得到精确的结果。

你现在接受了一个任务,要编写一个高精度计算器的核心部分。所谓高精度计算器,就是可以计算很大很大的数据的计算器。

输入:

输入的第一行是一个正整数,表示下面有几组数据需要计算。之后的每一行是两个十进制的正整数和一个运算符,每个整数可以由最多 500 个数字组成。运算符可以是加号或者减号。

输出:

对应着输入的每一行数据,输出计算的结果,每个结果占一行。

程序:

#include

#include

#define N 1010

void main()

{

char z, sign, a[N];

int n, i, j, f, x, b[N], c[N]; // b为数字1c为数字2

void add( int b[N], int c[N], int f );

void sub( int b[N], int c[N], int f );

scanf( "%d%c", &n, &z );

for( ; n>0; n--, printf("\n") )

{

gets( a );

x=strlen( a );

for( i=0; i

b[i]=c[i]=0;

for( i=x-1, j=0 ; '0'<=a[i] && a[i]<='9'; i--, j++)

c[j]=a[i]-'0';

f=j; //f为较长数字的长度

sign=a[i]; //sign为运算符

for( i--, j=0; i>=0; i--, j++)

b[j]=a[i]-'0';

if( f为较长数字的长度

if( sign=='+') add( b, c, f );

else sub( b, c, f );

}

}

void add( int b[N], int c[N], int f )

{

int i, r, d[N]; // r为进位数,d为运算结果

for( i=0, r=0; i

{

d[i]=(b[i]+c[i]+r)%10;

r=(b[i]+c[i]+r)/10;

}

if( r==1 ) printf("1");

for( i--; i>=0; i--)

printf("%d", d[i]);

}

void sub( int b[N], int c[N], int f )

{

int i, r, flag, d[N]; // r为进位数,d为运算结果

for( i=f-1, flag=1; i>=0; i-- )

{

if( b[i]>c[i] ) {flag=1;break;}

else if( b[i]

}

if( flag==1 )

{

for( i=0, r=0; i

{

d[i]=b[i]-c[i]+r;

if( d[i]<0 )

{

d[i]=d[i]+10;

r=-1;

}

else r=0;

}

}

if( flag==-1 )

{

printf("-");

for( i=0, r=0; i

{

d[i]=c[i]-b[i]+r;

if( d[i]<0 )

{

d[i]=d[i]+10;

r=-1;

}

else r=0;

}

}

for( i--; d[i]==0 && i>0 ; i--)

;

for( ; i>=0; i-- )

printf("%d", d[i]);

}

43. 缩写展开

在保存字符串时,对出现在连续位置的若干个字符,如这些字符在ASCII表中也是连续出现,则可以将这些字符使用缩写形式进行保存,以节省保存空间。例如用A-Z表示ABCD...XYZ1-5表示12345c-f表示cdef

输入:

包含缩写形式的字符串

输出:

将缩写形式进行还原后的字符串

说明:

只分别对大写字母、小写字母和数字进行压缩,对于形如9-Aa-C这样的缩写不进行处理。

程序:

#include

#include

int isBigLetter(char s)

{

if('A'<=s&&s<='Z')

{

return 1;

}

else return 0;

}

int isSmallLetter(char s)

{

if('a'<=s&&s<='z')

{

return 1;

}

else return 0;

}

int isNumber(char s)

{ if('0'<=s&&s<='9')

{

return 1;

}

else return 0;

}

void main()

{

char str[100];

gets(str);

int length,i,j;

length=strlen(str);

j=0;

char newstr[200];

char temp;

for(i=0;i

{

if(str[i]=='-')

{

if(isBigLetter(str[i-1])&&isBigLetter(str[i+1]))

{

if(str[i+1]>str[i-1])

{

for(temp=str[i-1]+1;temp

{

newstr[j]=temp;

j++;

}

}

else

{

newstr[j]=str[i];

j++;

}

}

else if(isSmallLetter(str[i-1])&&isSmallLetter(str[i+1]))

{

if(str[i+1]>str[i-1])

{

for(temp=str[i-1]+1;temp

{

newstr[j]=temp;

j++;

}

}

else

{

newstr[j]=str[i];

j++;

}

}

else if(isNumber(str[i-1])&&isNumber(str[i+1]))

{

if(str[i+1]>str[i-1])

{

for(temp=str[i-1]+1;temp

{

newstr[j]=temp;

j++;

}

}

else

{

newstr[j]=str[i];

j++;

}

}

else

{

newstr[j]=str[i];

j++;

}

}

else

{

newstr[j]=str[i];

j++;

}

}

newstr[j]='\0';

printf("%s\n",newstr);

}

44. 函数递归

编写一个函数,使用递归算法求满足下述定义的整数序列的第n项。

1

n >= 0 n <= 4

f( n ) =

f(n-1) + f(n-3)

n > 4 n为偶数

f(n-2) + f(n-4)

n > 4 n为奇数

-1

其他



函数原型如下:



int findf(int n);



参数说明:n 项数;返回值是第n项值。

例如输入:10,输出:8

预设代码

前置代码

1.

2. #include

3.

4. int main()

5. { int n,s, findf( int );

6. scanf("%d", &n);

7. s = findf(n);

8. printf("%d\n", s);

9. return 0;

10. }

程序:

int findf(int n)

{

int r;

if(n<0)

{

r=-1;

}

else if(n<=4&&n>=0)

{

r=1;

}

else

{

if(n%2==0)

{

r=findf(n-1)+findf(n-3);

}

else

{

r=findf(n-2)+findf(n-4);

}

}

return r;

}

45. 大家再来做游戏

还是那个大家做游戏的问题:

幼儿园的小朋友们刚学习了如何数数,阿姨在下课时组织大家一起玩游戏。规则如下:所有的小朋友绕成一圈,顺序排号,给出开始报数的小孩的编号后,从这个小朋友开始报数,凡是报到固定数字(例如5)的,都退出该游戏,接着从下一个小朋友在从1开始报数,直到只剩下一位小朋友游戏才中止。

输入: 小朋友的个数(<=50 开始报数的小孩的编号 要被练习的数字

输出: 最终被留下的小朋友的序号

例如输入:4 1 3

输出:The left child is NO 1.

说明:这次,以函数的方式实现上述问题。主函数已经给出,仅需提交自己编写的函数。你可以尝试用递归方法来解决呦!

这个问题是著名的约瑟夫问题,基于著名犹太历史学家 Josephus讲述的一个,所以函数的名字是josephus

函数原型:

int josephus( int * boy, int n, int m, int r)

参数说明:

int * boy:保存参加游戏的小孩编号的整型数组的首地址。小孩的编号从1开始。

int n:开始参加游戏的小孩总数。

int m:开始时第一次报数的小孩的编号。

int r:要被练习的数字。

预设代码

josephus.c

1. #include "stdio.h"

2. int josephus( int *boy, int n, int m, int r );

3.

4. int main( )

5. { int i, boy[50]={0}, n, m, r;

6. scanf("%d%d%d",&n,&m,&r);

7. if( n<=0 || n>50 || m<=0 || m>50 || r<=0 )

8. printf("The number is wrong!\n" );

9. else

10. {

11. for( i=0; i

12. boy[i] = i + 1;

13. printf( "The left child is NO %d.\n", josephus( boy, n, m, r ) );

14. }

15. return 0;

16. }

程序:

josephus( int *boy, int n, int m, int r )

{

int j;

if(n>1)

{

if((m+r-1)%n!=0)

{

for(j=(m+r-1)%n-1;j

boy[j]=boy[j+1];

return josephus(boy,n-1,(m+r-1)%n,r);

}

else

{

return josephus(boy,n-1,1,r);

}

}

if(n=1)

{

return boy[0];

}

}

H18:拱猪计分(选作)

输入:

每个输入文件由多组测试数据构成,每组测试数据有四行,每一行第一个数为该玩家所持有计分牌总数,而后列出其所持有之所有计分牌,牌数与各计分牌均以一个以上的空格分开。相邻两组测试数据之间不会有空白行,读到四家持牌数都为 0 表示文件结束。

输出:

每一行输出一组测试数据对应的结果,依次输出各家所得分数,共四个整数 ( 含正负号,0 除外),相邻两个整数之间以一个空格分开,符号和数字间不可以有空格。每组输出间不需要有空白行。

程序:

#include "stdio.h"

int myinput(int card[],int number[])

{

int i,n;

char s[5];

for(i=0;i<4;i++)

{

scanf("%d",&n);

number[i]=n;

while(n--)

{

scanf("%s",s);

switch(s[0])

{

case 'S':card[13]=i;break;

case 'D':card[14]=i;break;

case 'C':card[15]=i;break;

case 'H':s[2]=='\0'?(card[s[1]-'1']=i):(card[s[2]-'1'+10]=i);

}

}

}

return number[0]+number[1]+number[2]+number[3];

}

int main()

{

int

value[15]={-50,-2,-3,-4,-5,-6,-7,-8,-9,-10,-20,-30,-40,-100,100},

card[16],

score[4]={0,0,0,0},

number[4],

i,s,

input();

while(myinput(card,number))

{

for(i=0,s=0;i<13;i++)

s+=card[i];

if(s%13)

{

for(i=0;i<15;i++)

score[card[i]]+=value[i];

}

else

{

if(card[0]==card[13]&&card[13]==card[14])

score[card[0]]+=500;

else

{

score[card[0]]+=200;

score[card[14]]+=value[14];

score[card[13]]+=value[13];

}

}

score[card[15]]+=number[card[15]]==1?50:score[card[15]];

for(i=0;i<4;i++)

printf("%s%d%s",score[i]>0?"+":"",score[i],i==3?"\n":" ");

for(i=0;i<4;i++)

score[i]=0;

}

return 0;

}

46 求表示方法

mn 均为自然数,m 可表示为一些不超过 n 的自然数之和,f(m,n) 为这种表示方式的数目。

例如,f(5,3)=5,有5种表示方法:3+23+1+12+2+12+1+1+11+1+1+1+1

请编写程序,计算f(m,n)的值。

输入:

m n

输出:

f(m,n)的值

程序:

#include

int f(int y,int x)

{

if(y==1) return 1;

if(x==1) return 1;

if(y

if(x==y) return 1+f(y,x-1);

return f(y,x-1)+f(y-x,x);

}

main()

{

int m,n;

scanf("%d%d",&m,&n);

printf("%d\n",f(m,n));

}

47.查找子字符串

编写一个函数,该函数的功能是在给定的字符串中查找可能的子字符串,该子字符串是由给定的同一字符组成的最长的字符串。

例如:给定字符串是“ asddrrddddds ”,给定的字符是‘ d ’ , 获得的子字符串是“ ddddd ”

函数原型: char * search(char *str, char ch)

参数说明: str 保存给定的字符串的首地址(字符串长度不大于100), ch 保存给定的字符。

函数返回值:找到的符合要求的子字符串的首地址。如果没有符合要求的子字符串,返回一个空指针。

预设代码

search_46.c

1. #include

2.

3. char *search( char *str, char ch );

4.

5. main()

6. {

7. char s[100] = {0}, ch, *p;

8. gets(s);

9. ch = getchar();

10. p = search( s, ch );

11. if( p == NULL )

12. printf("There is not the sub-string.");

13. else

14. while( *p == ch )

15. putchar( *p++ );

16. printf("\n");

17. }

程序:

#include

char *search( char *str, char ch )

{

int i,j=0,max=0,x,length=0,tag=0;

char *p;

for (i=0;*(str+i)!='\0';i++)

{

while (*(str+i)==ch)

{

tag=1;

j++;

if (j==1) x=i;

i++;

}

if (length

{

length=j;

max=x;

}

j=0;

}

if (tag==0) p=NULL;

if (tag==1) p=str+max;

return p;

}

48.元素值之和

编写函数,计算给定的整型数组的奇数元素值之和、偶数元素值之和。

例如数组元素的值依次为: 1 8 2 3 11 6 ;则奇数值之和 15 、偶数值之和 16

函数原型: void findsum( int *pa , int n, int *podd, int *peven )

参数说明: pa 是整型数组的首地址, n 是数组元素个数(元素个数不大于100),指针 podd peven 保存奇数之和、偶数之和的整型变量的地址。

返回值:无返回值。

预设代码

findsum_48.c

1. #include

2.

3. void findsum( int *pa, int n, int *podd, int *peven );

4.

5. main( )

6. {

7. int i, n, a[100], odd, even;

8. scanf( "%d",&n );

9. for( i=0; i

10. scanf("%d",&a[i] );

11. findsum( a, n, &odd, &even );

12. printf("odd=%d,even=%d\n", odd, even );

13. }

程序:

void findsum( int *pa, int n, int *podd, int *peven )

{

int i;

*podd=0;

*peven=0;

for(i=0;i

{

if(*(pa+i)%2==0)*peven=*peven+*(pa+i);

else *podd=*podd+*(pa+i);

}

}

H19:逆波兰算术表达式(选作)

传统的算术表达式是由操作数(又叫运算对象或运算量)和运算符以及改变运算次序的圆括号连接而成的式子。 其运算规则如下:

(1) 先计算括号内,后计算括号外;

(2) 在无括号或同层括号内,先进行乘除运算,后进行加减运算,即乘除运算的优先级高于加减运算的优先级;

(3) 同一优先级运算,从左向右依次进行。

在这种表达式的计算过程中,既要考虑括号的作用,又要考虑运算符的优先级,还要考虑运算符出现的先后次序。

波兰科学家卢卡谢维奇(Lukasiewicz)提出了算术表达式的另一种表示,即后缀表示,又称逆波兰式,其定义是把运算符放在两个运算对象的后面。在后缀表达式中,不存在括号,也不存在优先级的差别,计算过程完全按照运算符出现的先后次序进行,整个计算过程仅需一遍扫描便可完成。

例如:

3/5+6的逆波兰表达式为3 5 / 6 +

2*(3+4)的逆波兰表达式为2 3 4 + *

输入:

一个只包含加、减、乘、除和数字的逆波兰表达式

输出:

该表达式的值

程序:

#include

#include

#define N 50

int operation(char ch,int *k)

{

switch (ch){

case '+':return(*k + *(k+1));

case '-':return(*k - *(k+1));

case '*':return(*k * *(k+1));

case '/':return(*k / *(k+1));

default:return 0;}

}

int main()

{

int operation(char,int *);

static int number[N];

int i=0;

char sign[N],*p=sign;

gets(sign);

while(*p)

{

if (*p<='9'&&*p>='0')

number[i++]=atoi(p);

else

{ number[i-2]=operation(*p,&number[i-2]);i--; }

for(p++;!(*p!=' '&&*(p-1)==' ')&&*p;p++);

}

printf ("%d\n",number[0]);

return 0;

}

H20.计算子字符串个数

字符串匹配问题:输入一个字符串,计算其中包含的连续给定的子字符串的个数。

例如输入字符串“ EFABCABCABCDABCDD , 给定子字符串“ ABC ,输出是 3

函数原型: int countsub( char *str, char *subs )

参数说明: str 保存输入的字符串的首地址, subs 保存需要统计的子字符串的首地址。

返回值:包含的连续子字符串的个数。

预设代码

countsub_H20.c

1. #include

2.

3. int countsub( char *str, char *ss );

4.

5. main( )

6. {

7. char s1[1000] = {0}, s2[100] = {0};

8. gets(s1);

9. gets(s2);

10. printf("%d\n", countsub( s1, s2 ) );

11. }

程序:

int countsub( char *str, char *ss )

{

int i,j,q,k=0,r,max=0,flag=1,h;

for(r=0;str[r]!='\0';r++);

for(i=0;i<=r;)

{

for(j=i,q=0;j<=r;j++)

{

if(ss[q]=='\0')

{

h=q;

k++;

flag=0;

break;

}

if(str[j]==ss[q])

q++;

else

{

if(k>max)

max=k;

k=0;

flag=1;

break;

}

}

if(flag)

i++;

else

i=i+h;

}

return max;

}

49.为整数编号

使用以下结构

struct nn

{

int no;

int num;

};

建立一个结构数组,从键盘输入若干个整数,保存在数组元素的num成员中,并根据输入的数按从小到大进行编号,将编号保存在no成员中。按整数的输入顺序输出整数及其编号。输入的整数不超过100个,每个整数的绝对值不大于1000,输入时以空格分隔整数。

例如输入:4 3 6 8 2 3 9

输出:

4 4

3 2

6 5

8 6

2 1

3 3

9 7

要求:当两个整数相等时,整数的排列顺序由输入的先后次序决定。例如:输入的第2个整数为3,第6个整数也为3,则将先输入的整数3的编号在前,后输入的整数3的编号在后。编写函数完成为整数编号。

函数原型:int number( char *str, struct nn a[] );

其中:str:保存以字符串方式接收的键盘输入,

a 保存整数及编号的结构数组的首地址,

函数返回值:已输入的整数的个数。

预设代码

前置代码

1. #include

2. struct nn

3. { int no;

4. int num;

5. };

6.

7. typedef struct nn DATA;

8.

9. int number( char * , DATA []);

10.

11. int main( )

12. {

13. DATA b[100];

14. char sa[500];

15. int i, n;

16. gets( sa );

17. n = number( sa, b );

18. for ( i=0; i

19. printf("%d %d\n", b[i].num, b[i].no );

20. return 0;

21. }

22.

23. /* Here is waiting for you

24. int number( char * str, DATA a[] )

25. {

26. ....

27. }

28. */

程序:

int number( char * str, DATA a[] )

{

int n,i,j;

for(i=0;*(str+i)!='\0';i++)

n=(i+2)/2;

for(i=0;i

{

a[i].num=(int)*(str+2*i)-48;

a[i].no=1;

}

for(i=0;i

for(j=0;j

{

if(a[i].num>a[j].num)

a[i].no++;

else if(a[i].num==a[j].num&&(i>j))

a[i].no++;

else ;

}

return(n);

}

50.学生成绩排序

大家参加了期末考试,成绩出来后老师要对 n 个学生进行成绩汇总和排序。要求程序按成绩降序进行排序。在排序过程中对于成绩相同的学生,要按照输入数据的顺序进行排列。例如:有5名学生的成绩:

zhang1,90

zhang2,91

zhang3,99

zhang4,91

zhang5,98

则排序结果应该为:

zhang3,99

zhang5,98

zhang2,91

zhang4,91

zhang1,90

请注意例题中“zhang2”“zhang4”的排列顺序。

输入:

第一行为将要输入的学生数量n

从第二行起后面连续 n 行数据,每行为一名学生的姓名(长度不超过20个字符,不包括空格),考试成绩(int

输出:

排序后的结果。每行为一名学生的姓名和成绩。

程序:

#include

struct nn

{ char no[30];

int num;

};

typedef struct nn DATA;

int main( )

{ char str[30];

int i,j,n,k;

scanf("%d\n",&n);

DATA b[n];

for(i=0;i

{scanf("%s",&str);

k=strlen(str)-1;

if(str[k-2]==',')

b[i].num=(str[k]-'0')+(str[k-1]-'0')*10;

else

b[i].num=(str[k]-'0')+(str[k-1]-'0')*10+(str[k-2]-'0')*100;

strcpy(b[i].no,str);}

for(i=1;i

for(j=0;j

if(b[j].num

{strcpy(str,b[j].no);strcpy(b[j].no,b[j+1].no);strcpy(b[j+1].no,str);

k=b[j].num;b[j].num=b[j+1].num;b[j+1].num=k;}

for(i=0;i

printf("%s\n",b[i].no);

}

H21:数码管(选作)

背景

数码管是一种廉价的十进制数字显示装置,它的基本工作原理是:一个数码管有 7 段,我们将它对应成八位二进制的 8 位。这 8 位的编号从左向右分别是 76543210。数码管的一段对应二进制的一位,如果要点亮某一段,则需要将相应的二进制位置 1,其余不亮的段要将对应的位置 0。下图表示了 7 个二进制在数码管上对应的位置:

 2

+---+

3|   |4

| 1 |

+---+

5|   |6

| 0 |

+---+

例如,我们要显示出数字“1”,则应该点亮数码管的第46段。这样对应的8位二进制数就是:0101 0000。如果用十六进方式表示出来就是 50

同理,要显示出“3”,应该点亮:01246;对应的二进表示为:0101 0111,用十六进制表示就是 57

请编写一个程序,用 5 个数码管显示一个 16 (bit) 的正整数。

说明:如果需要显示的数据不足5位,则在数据前面补0。例如120要显示为00120

输入

程序的输入是一系列 16 (bit)的正整数(10进制形式),数与数之间允许用空白符隔开,当数字为 0 时程序结束。

输出

针对每个正整数,输出 5 个字节的十六进制数,它们可以表示 5 个数码管的状态。其中右侧第 1 个数表示输入数字的个位,第 2 个数表示十位,以此类推。

程序:#include

#include

int main()

{

char w[100];

int num[10]={125,80,55,87,90,79,111,84,127,95};

int s=4,l=0;

int n[9]={0,0,0,0,0,0,0,0,0};

for(;1;)

{

s=4;

gets(w);

if(w[0]=='0')

break;

l=strlen(w);

for(int i=0;i<=l;i++)

{

if(w[i]==' '&&s==4)

continue;

else if(w[i]==' '||s==9)

{

for(int q=s-4;q

{

printf("%X",num[n[q-1]]);

if(q!=s)

printf(" ");

}

printf("\n");

for(int x=0;x<9;x++)

n[x]=0;

s=4;

}

else if(w[i]=='\0'&&s==4)

continue;

else if(w[i]=='\0')

{

for(int q=s-4;q

{

printf("%X",num[n[q-1]]);

if(q!=s)

printf(" ");

}

printf("\n");

for(int x=0;x<9;x++)

n[x]=0;

s=4;

continue;

}

else

{

n[s]=w[i]-'0';

s++;

}

}

}

}

51.建立链表

请按照输入整数的顺序建立一个倒序的带表头节点的链表。已知程序的基本结构如下,请你编写 ins_list 函数。

预设代码

前置代码

1. #include "stdio.h"

2. struct node

3. { int data;

4. struct node * next;

5. } ;

6.

7. typedef struct node NODE;

8. typedef struct node * PNODE;

9.

10. int main ( )

11. { int num=1;

12. PNODE head;

13.

14. head = (PNODE)malloc( sizeof(NODE) );

15. head->next = NULL;

16. head->data = -1;

17.

18. while ( num!=0 )

19. { scanf("%d", &num);

20. if ( num!=0 )

21. ins_list( head, num);

22. }

23.

24. outlist( head );

25. return 0;

26. }

27.

28. outlist( PNODE head )

29. { PNODE p;

30. p = head->next;

31. while ( p != NULL )

32. { printf("%d\n", p->data);

33. p = p->next;

34. }

35. }

程序:

void ins_list( PNODE h, int num )

{

PNODE p;

p=(PNODE)malloc(sizeof(NODE));

p->data=num;

p->next=h->next;

h->next=p;

}

52.链表处理*

编写一个函数,给定的带有头结点的单向链表 head,给定某结点的数据域值 m,将该结点移到链首。

结构的定义:

typedef struct node

{

int num;

struct node *next;

} SNODE;

函数的原型:SNODE *movenode(SNODE *head, int m);

其中:参数 head 是单向链表的头指针;参数 m 是某结点的num成员的值。

例如输入结点数 n=7,则将结点数值域值 m=5 的结点移动到链首。函数运行前后链表的情况如下图所示。

预设代码

前置代码

1. #include

2. #include

3.

4. typedef struct sdata

5. { int num;

6. struct sdata *next;

7. } SNODE;

8.

9. void movenode( SNODE *, int );

10.

11. void setlink( SNODE * head, int n )

12. {

13. SNODE *p;

14.

15. while ( n > 0 )

16. { p = ( SNODE * ) malloc( sizeof( SNODE ) );

17. p->num = n;

18. p->next = head->next;

19. head->next = p;

20. n --;

21. }

22. }

23.

24. void outlink( SNODE * head )

25. {

26. while( head->next != NULL )

27. {

28. head = head->next;

29. printf( "%d,", head->num );

30. }

31. return;

32. }

33.

34. int main( )

35. { int n, m;

36. SNODE * head = NULL;

37.

38. scanf("%d%d", &n, &m );

39. head = ( SNODE * ) malloc( sizeof( SNODE ) );

40. head->num = -1;

41. head->next = NULL;

42. setlink( head, n );

43.

44. movenode( head, m ); /* This is waiting for you. */

45.

46. outlink( head );

47. printf("\n");

48. return 0;

49. }

程序:

void movenode( SNODE *head, int m)

{ SNODE * p,*q,*k;

q=( SNODE * ) malloc( sizeof( SNODE ) );

p=head;

k=head;

int c=0;

while(k->next!=NULL){

c++;

k=k->next ;

}

while(p->next->num !=m){

if(m==0||m>c) break;

p=p->next ;

}

q->num=p->next->num ;

p->next =p->next->next ;

q->next=head->next ;

head->next =q;

}

53.猜数字看人品

描述

Tom Jerry 做猜数字的游戏,Tom 想一个数字然后让 Jerry 去猜,数字的范围在 1 10 之间。对于 Jerry 每讲的一个数,Tom 都要讲这个数是 too high 或者 too low 或者 right on,直到 right on 结束。为了防止 Tom 作弊,Jerry 把每一次的对话记录下来,现在让你去判断 Tom 有没有作弊。

输入

游戏可能做很多次,直到 Jerry 0 的时候游戏结束,每一次猜测由一个正整数和一行回答组成。

输出

对每一次游戏如果 Tom 的回答有自相矛盾的地方,就输出 Tom is dishonest,否则输出 Tom may be honest

程序:

#include

int backtobase(int *p) //初始化110数组

{

for(int i=1;i<=10;i++)

{

*p=i;

p++;

}

return 0;

}

int cleanright(int *right,int n)

{

for(int i=n;i<=10;i++)

{

*right=0;

right++;

}

return 0;

}

int cleanleft(int *left,int n)

{

for(int i=n;i>=1;i--)

{

*left=0;

left--;

}

return 0;

}

int main()

{

int base10[11]={0,0,0,0,0,0,0,0,0,0,0};

int *p;

int *right;

right=NULL;

int *left;

left=NULL;

p=&base10[1];

backtobase(p);

char cmd[20];

int n=0;

int c=0; //switch case

for(int q=0;q<1;)

{

char temp;

scanf("%d",&n);

temp=getchar();

gets(cmd);

if (n==0)

{break;}

if (cmd[4]=='h')

c=1; //1 high

else if(cmd[4]=='l')

c=2; //2 low

else if(cmd[4]=='t')

c=3; //3 right

else

c=0; //0 error

switch (c)

{

case 1:

{

right=&base10[n];

cleanright(right,n);

break;

}

case 2:

{

left=&base10[n];

cleanleft(left,n);

break;

}

case 3:

{

if (base10[n]==0)

printf("Tom is dishonest\n");

else

printf("Tom may be honest\n");

backtobase(p);

c=0;

break;

}

case 0:

{

break;}

}

}

}

H22 恭喜发财 利是窦来(选做)

在中国,过春节时人们有给孩子压岁钱(粤语称为利是)的习俗。

最早的压岁钱出现于汉代,又叫压胜钱,并不在市面上流通,而是铸成钱币形式的玩赏物,有避邪的功能。钱币正面一般铸有“万岁千秋”、“去殃除凶”等吉祥话和龙凤、龟蛇、双鱼等吉祥图案。

据说嘉兴府有一户姓管的人家,夫妻老年得子,十分珍爱。在年三十晚上,为防止“祟”来侵扰 一直逗孩子玩,小孩用红纸包了八枚铜钱,包了又拆,拆了又包,睡下以后,包着的八枚铜钱就放在枕边。半夜里,一阵阴风吹过,黑矮的小人正要用他的白手摸孩 子的头,突然孩子枕边迸出一道金光,祟尖叫着逃跑了。

于是这件事传扬开来,大家纷纷效仿,在大年夜用红纸包上钱给孩子,祟就不敢再来侵扰了。因而人们把这种钱叫“压祟钱”,“祟”与“岁”发音相同,日久天长,就被称为 “压岁钱”了。

现在有 N 个人,他们都有小孩,春节来了,他们要发压岁钱给朋友的小孩,而他们自己的小孩也会收到压岁钱。为了简单,他们在发压岁钱的时候,使用以下的计算方法,譬 如某甲有 100 块,它要给另外三个人的小孩发压岁钱,则每个小孩会分到 100/3 = 33 块,剩余的 1 块就不发了。

给你这 N 个人的信息,以及他们把压岁钱发给了谁的小孩,请你计算他们每个人的小孩收到的压岁钱和他们发出去的压岁钱的差额是多少。

输入

1 : 一个整数 N2 <= N <= 10)

2..N+1 : 每行是一个人名,每个名字不超过 14 个字符

N+2..结束: N 组按照以下规则组织的数据:

组中的第一行为送出压岁钱的人名。

第二行包括两个数字,第一个是该人有多少钱(0~2000),第二个是它要把钱发给几个人的小孩,用 NGi 表示(0 NGi N-1).

如果 NGi 为非零,则下面的 NGi 行会列出接受压岁钱的人的名字。

程序:

#include

#include

#include

struct date

{

char name[15];

int money;

int get;

int num;

int res;

};

int main()

{

struct date people[10];

for(int x=0;x<10;x++)

{

people[x].get=0;

}

int n,itemp,ktemp,ntemp,moneytemp;

char temp[20];

scanf("%d",&n);

for(int i=0;i

{

scanf("%s",people[i].name);

}

for(int a=0;a

{

scanf("%s",temp);

for(itemp=0;strcmp(temp,people[itemp].name);itemp++)

{;}

scanf("%d%d",&people[itemp].money,&ntemp);

if(ntemp!=0)

moneytemp=people[itemp].money/ntemp;

people[itemp].num=ntemp;

while(ntemp--)

{

scanf("%s",temp);

for(ktemp=0;strcmp(temp,people[ktemp].name);ktemp++)

{;}

people[ktemp].get+=moneytemp;

}

}

for(int a=0;a

{

if(people[a].num)

{

people[a].res=people[a].get-people[a].money+people[a].money%people[a].num;

}

else

{

people[a].res=people[a].get;

}

}

for (int a=0;a

{

printf("%s %d\n",people[a].name,people[a].res);

}

}

54.链表排序

对于输入的 n 个数据 num 进行排序,要求将输入的数据按 num 升序建立带有表头结点的链表,且链表中不能有重复的数据。

  现在已经给出结点定义和程序框架,包括 main 函数和链表输出函数 outlist,请编写函数 sortlist 完成链表排序功能。

函数原型 sortlist( PNODE h, int num ) 的参数含义如下:

h :单链表的头指针

num :新输入的需要插入链表中的数据

预设代码

前置代码

1. #include "stdio.h"

2. struct node

3. { int data;

4. struct node * next;

5. } ;

6.

7. typedef struct node NODE;

8. typedef struct node * PNODE;

9.

10. int main ( )

11. { int num=1;

12. PNODE head;

13.

14. head = (PNODE)malloc( sizeof(NODE) );

15. head->next = NULL;

16. head->data = -1;

17.

18. while ( num!=0 )

19. { scanf("%d", &num);

20. if ( num!=0 )

21. sortlist( head, num);

22. }

23. outlist( head );

24. return 0;

25. }

26.

27. outlist( PNODE head )

28. { PNODE p;

29. p = head->next;

30. while ( p != NULL )

31. { printf("%d\n", p->data);

32. p = p->next;

33. }

34. }

35.

36. /* This is an example for list. Please programme your code like it.

37. sortlist( PNODE h, int num )

38. { PNODE p;

39. p = (PNODE)malloc( sizeof(NODE) );

40. p->data = num;

41. p->next = h->next;

42. h->next = p;

43. }

程序:

void sortlist( PNODE h, int num )

{

PNODE p,ptemp;

p = (PNODE)malloc( sizeof(NODE) );

p->data = num;

ptemp=h;

while((ptemp->next)!=NULL)//find the first bigger than num

{

if(num<=ptemp->data)

{

break;

}

ptemp=ptemp->next;

}

if(num==ptemp->data)

{

free(p);

}

else if (num>ptemp->data)

{

p->next=ptemp->next;

ptemp->next=p;

}

else if (numdata)

{

int temp;

temp=ptemp->data;

ptemp->data=num;

p->data=temp;

p->next=ptemp->next;

ptemp->next=p;

}

}

55.链表节点排序

请编写函数 sortlist,按照成员data的数值从大到小的顺序建立带有表头结点的链表,且链表中不能有重复的数据。

已知定义如下:

struct node

{ int data;

struct node * next;

};

typedef struct node NODE;

typedef struct node * PNODE;

函数原型 sortlist( PNODE h, int num ) 的参数含义如下:

h :单链表的头指针

num :新输入的需要插入链表中的数据

注意:仅提交自编的sortlist函数,不提交main函数。

预设代码

2012_56.c

1. #include "stdio.h"

2. #include "stdlib.h"

3. struct node

4. { int data;

5. struct node * next;

6. } ;

7.

8. typedef struct node NODE;

9. typedef struct node * PNODE;

10.

11. int main( )

12. { int num=1;

13. PNODE head;

14. void sortlist( ), outlist( );

15. head = ( PNODE )malloc( sizeof(NODE) );

16. head->next = NULL;

17. head->data = -1;

18. while( num!=0 )

19. { scanf( "%d", &num ) ;

20. if( num!=0 )

21. sortlist( head , num ) ;

22. }

23. outlist( head ) ;

24. return 0;

25. }

26.

27. void outlist( PNODE head )

28. { PNODE p;

29. p = head->next;

30. while( p != NULL )

31. { printf("%d\n", p->data);

32. p = p->next;

33. }

34. }

程序:

#include "stdio.h"

#include"stdlib.h"

struct node

{ int data;

struct node * next;

} ;

typedef struct node NODE;

typedef struct node * PNODE;

sortlist( PNODE h, int num )

{ PNODE p;

p = (PNODE)malloc( sizeof(NODE) );

p->data = num;

while(h->next!=NULL)

{

if(p->data>h->next->data) break;

else if(p->data==h->next->data) return 0;

else h=h->next;

}

p->next = h->next;

h->next = p;

}

56.猜猜我是谁

在指定的文本文件中包含了我需要的信息,请从指定文件中读取指定的行。如果文件中没有指定的行,则显示“Line No Error.”。如果文件不存在,则显示“File Name Error.”。

输入:

第一行为要以只读方式打开的文本文件名

第二行要读取的行号(从1开始)

输出:

文件中指定行号的内容(完整一行的内容)

数据文件:data1.txt

程序:

#include

void main()

{

FILE * p;

int l,i,flag=0;

char file[30],ch,s[20];

scanf("%s",file);

if((p=fopen(file,"r"))==NULL)

{

printf("File Name Error.\n");

exit(0);

}

scanf("%d",&l);

if(l>4)

{

flag=1;

printf("Line No Error.\n");

}

if(flag==0)

{

for(i=0;i

{

fgets(s,17,p);

}

printf("%s",s);

}

fclose(p);

}

本文来源:https://www.2haoxitong.net/k/doc/033f749e14791711cc7917b0.html

《北理乐学C语言答案,最新.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档

文档为doc格式