C语言进阶题库
- 1.约瑟夫生者死者小游戏
- 2. 五人分鱼
- 3.有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
- 4.企业发放的奖金根据利润提成
- (1)优化如下:
- (2)使用循环优化代码的适用性:
- (3)利用 switch 的击穿现象
- 5.一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?
- 6.输入某年某月某日,判断这一天是这一年的第几天?
- 7.输入三个整数x,y,z,请把这三个数由小到大输出
- 8.打印出所有的"水仙花数"
- 9.将一个正整数分解质因数
- 10.利用条件运算符的嵌套来完成此题:学习成绩>=90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示
- 11.求s=a+aa+aaa+aaaa+aa...a的值
- 12.一个数如果恰好等于它的因子之和,这个数就称为"完数"。例如6=1+2+3.编程找出1000以内的所有完数
- 13.小球自由下落
- 14.猴子吃桃问题
- 15.两个乒乓球队进行比赛,各出三人
- 16.有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和
- 17.有5个人坐在一起,问第五个人多少岁?
- 18.回文数
- 19.删除一个字符串中的指定字母,如:字符串 "aca",删除其中的 a 字母
- 20.对10个数进行排序
- 21.有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中
- 22.将一个数组逆序输出
- 23.有 n个整数,使其前面各数顺序向后移 m 个位置,最后m个数变成最前面的 m 个数
- 24.有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位
- 25.创建一个链表
- 26.反向输出一个链表
- 27.连接两个链表
- 28.海滩上原来最少有多少个桃子?
- 29.809*??=800*??+9*?? 其中??代表的两位数, 809*??为四位数,8*??的结果为两位数,9*??的结果为3位数。求??代表的两位数,及809*??后的结果
- 30.电话号码加密
- 31.猜谜游戏
- 32.计算字符串中子串出现的次数
1.约瑟夫生者死者小游戏
30 个人在一条船上,超载,需要 15 人下船。
于是人们排成一队,排队的位置即为他们的编号。
报数,从 1 开始,数到 9 的人下船。
如此循环,直到船上仅剩 15 人为止,问都有哪些编号的人下船了呢?
#include<stdio.h>
int c = 0;
int i = 1;
int j = 0;
int a[30] = { 0 };
int b[30] = { 0 };
int main()
{
while (i<=31)
{
if (i == 31)
{
i = 1;
}
else if (c == 15)
{
break;
}
else
{
if (b[i] != 0)
{
i++;
continue;
}
else
{
j++;
if (j != 9)
{
i++;
continue;
}
else
{
b[i] = 1;
a[i] = j;
j = 0;
printf("第%d号下船了\n", i);
i++;
c++;
}
}
}
}
}
输出结果:
第9号下船了
第18号下船了
第27号下船了
第6号下船了
第16号下船了
第26号下船了
第7号下船了
第19号下船了
第30号下船了
第12号下船了
第24号下船了
第8号下船了
第22号下船了
第5号下船了
第23号下船了
2. 五人分鱼
A、B、C、D、E 五人在某天夜里合伙去捕鱼,到第二天凌晨时都疲惫不堪,于是各自找地方睡觉。
日上三杆,A 第一个醒来,他将鱼分为五份,把多余的一条鱼扔掉,拿走自己的一份。
B 第二个醒来,也将鱼分为五份,把多余的一条鱼扔掉拿走自己的一份。 。
C、D、E依次醒来,也按同样的方法拿鱼。
问他们台伙至少捕了多少条鱼?以及每个人醒来时见到了多少鱼?
#include <stdio.h>
int main(){
int n,x,j,k,l,m;
for(n=5;;n++){
j=4*(n-1)/5;
k=4*(j-1)/5;
l=4*(k-1)/5;
m=4*(l-1)/5;
if(n%5==1&&j%5==1&&k%5==1&&l%5==1&&m%5==1){
printf("至少合伙捕鱼:%d条\n",n);
printf("分别见到鱼的条数:%d %d %d %d\n",j,k,l,m);
break;
}
}
return 0;
}
输出结果:
至少合伙捕鱼:3121条
分别见到鱼的条数:2496 1996 1596 1276
3.有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
程序分析:可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去 掉不满足条件的排列
#include<stdio.h>
int main()
{
int i,j,k;
printf("\n");
for(i=1;i<5;i++) { // 以下为三重循环
for(j=1;j<5;j++) {
for (k=1;k<5;k++) { // 确保i、j、k三位互不相同
if (i!=k&&i!=j&&j!=k) {
printf("%d,%d,%d\n",i,j,k);
}
}
}
}
}
输出结果:
1,2,3
1,2,4
1,3,2
1,3,4
1,4,2
1,4,3
2,1,3
2,1,4
2,3,1
2,3,4
2,4,1
2,4,3
3,1,2
3,1,4
3,2,1
3,2,4
3,4,1
3,4,2
4,1,2
4,1,3
4,2,1
4,2,3
4,3,1
4,3,2
4.企业发放的奖金根据利润提成
• 利润(I)低于或等于10万元时,奖金可提10%;
• 利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%;
• 20万到40万之间时,高于20万元的部分,可提成5%;
• 40万到60万之间时高于40万元的部分,可提成3%;
• 60万到100万之间时,高于60万元的部分,可提成1.5%;
• 高于100万元时,超过100万元的部分按1%提成。
从键盘输入当月利润I,求应发放奖金总数?
程序分析:请利用数轴来分界,定位。注意定义时需把奖金定义成长整型。
#include<stdio.h>
int main()
{
double i;
double bonus1,bonus2,bonus4,bonus6,bonus10,bonus;
printf("你的净利润是:\n");
scanf("%lf",&i);
bonus1=100000*0.1;
bonus2=bonus1+100000*0.075;
bonus4=bonus2+200000*0.05;
bonus6=bonus4+200000*0.03;
bonus10=bonus6+400000*0.015;
if(i<=100000) {
bonus=i*0.1;
} else if(i<=200000) {
bonus=bonus1+(i-100000)*0.075;
} else if(i<=400000) {
bonus=bonus2+(i-200000)*0.05;
} else if(i<=600000) {
bonus=bonus4+(i-400000)*0.03;
} else if(i<=1000000) {
bonus=bonus6+(i-600000)*0.015;
} else if(i>1000000) {
bonus=bonus10+(i-1000000)*0.01;
}
printf("提成为:bonus=%lf",bonus);
printf("\n");
}
输出结果:
你的净利润是:
120000
提成为:bonus=11500.000000
(1)优化如下:
#include <stdio.h>
#define WAN 10000
int main()
{
double I = 0; // 利润
double B = 0; // 奖金
scanf("%lf", &I);
I /= WAN;
if (I > 100 * WAN)
{
B += ((I - 100) * 0.01);
I = 100;
}
if (I > 60)
{
B += ((I - 60) * 0.015);
I = 60;
}
if (I > 40)
{
B += ((I - 40) * 0.03);
I = 40;
}
if (I > 20)
{
B += ((I - 20) * 0.05);
I = 20;
}
if (I > 10)
{
B += ((I - 10) * 0.075);
I = 10;
}
B += (I * 0.1);
printf("%lf", B);
}
(2)使用循环优化代码的适用性:
#include<stdio.h>
int main()
{
int i;
double lirun;
double jiangjin = 0;
float fanwei[] = {100000, 200000, 400000, 600000, 1000000};
float ticheng[] = {0.1, 0.075, 0.05, 0.03, 0.015, 0.01};
printf("您好,请问您的净利润是多少?\n");
scanf("%lf", &lirun);
for (i=0;i<5;i++)
{
if (lirun < fanwei[i])
{
jiangjin += lirun * ticheng[i];
break;
}
else
{
jiangjin += fanwei[i] * ticheng[i];
lirun -= fanwei[i];
}
}
printf("奖金是%.2lf\n", jiangjin);
return 0;
}
(3)利用 switch 的击穿现象
#include <stdio.h>
int main(){
double d;
int money = 100000;
float res=0.0;
int flag;
scanf("%lf",&d);
flag = (int)(d/money);
flag = flag >10?10:flag;
switch(flag){
case 10:
res += (d-10*money)*0.01;
d = 10*money;
case 9:
case 8:
case 7:
case 6:
res += (d-6*money)*0.015;
d = 6*money;
case 5:
case 4:
res+= (d-4*money)*0.03;
d = 4*money;
case 3:
case 2:
res += (d-2*money)*0.05;
d = 2*money;
case 1:
res += (d-money)*0.075;
d = money;
case 0:
res += d *0.1;
}
printf("%.2f\n",res);
return 0;
}
5.一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?
程序分析:
假设该数为 x。
1、则:x + 100 = n2, x + 100 + 168 = m2
2、计算等式:m2 - n2 = (m + n)(m - n) = 168
3、设置: m + n = i,m - n = j,i * j =168,i 和 j 至少一个是偶数
4、可得: m = (i + j) / 2, n = (i - j) / 2,i 和 j 要么都是偶数,要么都是奇数。
5、从 3 和 4 推导可知道,i 与 j 均是大于等于 2 的偶数。
6、由于 i * j = 168, j>=2,则 1 < i < 168 / 2 + 1。
7、接下来将 i 的所有数字循环计算即可。
#include <stdio.h>
int main (void)
{
int i, j, m, n, x;
for (i = 1; i < 168 / 2 + 1; i++)
{
if (168 % i == 0)
{
j = 168 / i;
if ( i > j && (i + j) % 2 == 0 && (i - j) % 2 == 0)
{
m = (i + j) / 2;
n = (i - j) / 2;
x = n * n - 100;
printf ("%d + 100 = %d * %d\n", x, n, n);
printf ("%d + 268 = %d * %d\n", x, m, m);
}
}
}
return 0;
}
输出结果:
-99 + 100 = 1 * 1
-99 + 268 = 13 * 13
21 + 100 = 11 * 11
21 + 268 = 17 * 17
261 + 100 = 19 * 19
261 + 268 = 23 * 23
1581 + 100 = 41 * 41
1581 + 268 = 43 * 43
6.输入某年某月某日,判断这一天是这一年的第几天?
程序分析:以3月5日为例,应该先把前两个月的加起来,然后再加上5天即本年的第几天,特殊情况,闰年且输入月份大于3时需考虑多加一天
#include <stdio.h>
int main()
{
int day,month,year,sum,leap;
printf("\n请输入年、月、日,格式为:年,月,日(2021,7,2)\n");
scanf("%d,%d,%d",&year,&month,&day); // 格式为:2021,7,2
switch(month) // 先计算某月以前月份的总天数
{
case 1:sum=0;break;
case 2:sum=31;break;
case 3:sum=59;break;
case 4:sum=90;break;
case 5:sum=120;break;
case 6:sum=151;break;
case 7:sum=181;break;
case 8:sum=212;break;
case 9:sum=243;break;
case 10:sum=273;break;
case 11:sum=304;break;
case 12:sum=334;break;
default:printf("data error");break;
}
sum=sum+day; // 再加上某天的天数
if(year%400==0||(year%4==0&&year%100!=0)) {// 判断是不是闰年
leap=1;
} else {
leap=0;
}
if(leap==1&&month>2) { // *如果是闰年且月份大于2,总天数应该加一天
sum++;
}
printf("这是这一年的第 %d 天。",sum);
printf("\n");
}
输出结果:
请输入年、月、日,格式为:年,月,日(2015,12,10)
2021,7,2
这是这一年的第 183 天。
7.输入三个整数x,y,z,请把这三个数由小到大输出
程序分析:我们想办法把最小的数放到x上,先将x与y进行比较,如果x>y则将x与y的值进行交换,然后再用x与z进行比较,如果x>z则将x与z的值进行交换,这样能使x最小
#include <stdio.h>
int main()
{
int x,y,z,t;
printf("\n请输入三个数字:\n");
scanf("%d%d%d",&x,&y,&z);
if (x>y) { /*交换x,y的值*/
t=x;x=y;y=t;
}
if(x>z) { /*交换x,z的值*/
t=z;z=x;x=t;
}
if(y>z) { /*交换z,y的值*/
t=y;y=z;z=t;
}
printf("从小到大排序: %d %d %d\n",x,y,z);
}
输出结果:
请输入三个数字:
1
3
2
从小到大排序: 1 2 3
8.打印出所有的"水仙花数"
题目:打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数 本身。例如:153是一个"水仙花数",因为153=1的三次方+5的三次方+3的三次方。
程序分析:利用for循环控制100-999个数,每个数分解出个位,十位,百位。
#include<stdio.h>
int main()
{
int i,x,y,z;
for(i=100;i<1000;i++)
{
x=i%10;
y=i/10%10;
z=i/100%10;
if(i==(x*x*x+y*y*y+z*z*z))
printf("%d\n",i);
}
return 0;
}
输出结果:
153
370
371
407
9.将一个正整数分解质因数
题目:将一个正整数分解质因数。例如:输入90,打印出90=233*5。
程序分析:对n进行分解质因数,应先找到一个最小的质数k,然后按下述步骤完成:
• (1)如果这个质数恰等于(小于的时候,继续执行循环)n,则说明分解质因数的过程已经结束,另外 打印出即可。
• (2)但n能被k整除,则应打印出k的值,并用n除以k的商,作为新的正整数n.重复执行第二步。
• (3)如果n不能被k整除,则用k+1作为k的值,重复执行第一步。
#include<stdio.h>
int main()
{
int n,i;
printf("请输入整数:");
scanf("%d",&n);
printf("%d=",n);
for(i=2;i<=n;i++)
{
while(n%i==0)
{
printf("%d",i);
n/=i;
if(n!=1) printf("*");
}
}
printf("\n");
return 0;
}
输出结果:
请输入整数:90
90=233*5
10.利用条件运算符的嵌套来完成此题:学习成绩>=90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示
程序分析:(a>b)?a:b这是条件运算符的基本例子。
#include<stdio.h>
int main()
{
int score;
char grade;
printf("请输入分数: ");
scanf("%d",&score);
grade=(score>=90)?'A':((score>=60)?'B':'C');
printf("%c\n",grade);
return 0;
}
输出结果:
请输入分数: 87
B
11.求s=a+aa+aaa+aaaa+aa…a的值
题目:求s=a+aa+aaa+aaaa+aa…a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加有键盘控制。
程序分析:关键是计算出每一项的值。
#include<stdio.h>
int main()
{
int s=0,a,n,t;
printf("请输入 a 和 n:\n");
scanf("%d%d",&a,&n);
t=a;
while(n>0)
{
s+=t;
a=a*10;
t+=a;
n--;
}
printf("a+aa+...=%d\n",s);
return 0;
}
输出结果:
请输入 a 和 n:
2 5
a+aa+…=24690
12.一个数如果恰好等于它的因子之和,这个数就称为"完数"。例如6=1+2+3.编程找出1000以内的所有完数
#include<stdio.h>
#define N 1000
int main()
{
int i,j,k,n,sum;
int a[256];
for(i=2;i<=N;i++)
{
sum=a[0]=1;
k=0;
for(j=2;j<=(i/2);j++)
{
if(i%j==0)
{
sum+=j;
a[++k]=j;
}
}
if(i==sum)
{
printf("%d=%d",i,a[0]);
for(n=1;n<=k;n++)
printf("+%d",a[n]);
printf("\n");
}
}
return 0;
}
输出结果:
6=1+2+3
28=1+2+4+7+14
496=1+2+4+8+16+31+62+124+248
13.小球自由下落
题目:一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?
程序分析:见下面注释。
#include<stdio.h>
int main()
{
float h,s;
h=s=100;
h=h/2; //第一次反弹高度
for(int i=2;i<=10;i++)
{
s=s+2*h;
h=h/2;
}
printf("第10次落地时,共经过%f米,第10次反弹高%f米\n",s,h);
return 0;
}
输出结果:
第10次落地时,共经过299.609375米,第10次反弹高0.097656米
14.猴子吃桃问题
题目:猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个
第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下
的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。
程序分析:采取逆向思维的方法,从后往前推断。
- 设x1为前一天桃子数,设x2为第二天桃子数, 则:
x2=x1/2-1, x1=(x2+1)*2
x3=x2/2-1, x2=(x3+1)*2
以此类推: x前=(x后+1)*2 - 从第10天可以类推到第1天,是一个循环过程。
#include <stdio.h>
#include <stdlib.h>
int main(){
int day, x1 = 0, x2;
day=9;
x2=1;
while(day>0) {
x1=(x2+1)*2; // 第一天的桃子数是第2天桃子数加1后的2倍
x2=x1;
day--;
}
printf("总数为 %d\n",x1);
return 0;
}
输出结果:
总数为 1534
15.两个乒乓球队进行比赛,各出三人
题目:两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。
#include <stdio.h>
#include <stdlib.h>
int main()
{
char i,j,k;
for(i='x';i<='z';i++) {
for(j='x';j<='z';j++) {
if(i!=j) {
for(k='x';k<='z';k++) {
if(i!=k&&j!=k) {
if(i!='x'&&k!='x'&&k!='z') {
printf("顺序为:a--%c\tb--%c\tc--%c\n",i,j,k);
}
}
}
}
}
}
}
输出结果:
顺序为:a–z b–x c–y
16.有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13…求出这个数列的前20项之和
#include <stdio.h>
int main()
{
int i,t;
float sum=0;
float a=2,b=1;
for(i=1;i<=20;i++)
{
sum=sum+a/b;
t=a;
a=a+b;
b=t;
}
printf("%9.6f\n",sum);
}
输出结果:
32.660263
17.有5个人坐在一起,问第五个人多少岁?
题目:有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第3个人大2岁。问第三个人,又说比第2人大两岁。问第2个人,说比第一个人大两岁。最后问第一个人,他说是10岁。请问第五个人多大?
程序分析:利用递归的方法,递归分为回推和递推两个阶段。要想知道第五个人岁数,需知道第四人的岁数,依次类推,推到第一人(10岁),再往回推。
#include <stdio.h>
int age(n)
int n;
{
int c;
if(n==1) c=10;
else c=age(n-1)+2;
return(c);
}
int main()
{
printf("%d\n",age(5));
}
输出结果:
18
18.回文数
题目:一个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。
程序分析:学会分解出每一位数。
#include <stdio.h>
int main( )
{
long ge,shi,qian,wan,x;
printf("请输入 5 位数字:");
scanf("%ld",&x);
wan=x/10000; /*分解出万位*/
qian=x%10000/1000; /*分解出千位*/
shi=x%100/10; /*分解出十位*/
ge=x%10; /*分解出个位*/
if (ge==wan&&shi==qian) { /*个位等于万位并且十位等于千位*/
printf("这是回文数\n");
} else {
printf("这不是回文数\n");
}
}
输出结果:
请输入 5 位数字:12321
这是回文数
请输入 5 位数字:12345
这不是回文数
19.删除一个字符串中的指定字母,如:字符串 “aca”,删除其中的 a 字母
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
// 删除字符串中指定字母函数
char* deleteCharacters(char * str, char * charSet)
{
int hash [256];
if(NULL == charSet)
return str;
for(int i = 0; i < 256; i++)
hash[i] = 0;
for(int i = 0; i < strlen(charSet); i++)
hash[charSet[i]] = 1;
int currentIndex = 0;
for(int i = 0; i < strlen(str); i++)
{
if(!hash[str[i]])
str[currentIndex++] = str[i];
}
str[currentIndex] = '\0';
return str;
}
int main()
{
char s[2] = "a"; // 要删除的字母
char s2[5] = "aca"; // 目标字符串
printf("%s\n", deleteCharacters(s2, s));
return 0;
}
输出结果:
c
20.对10个数进行排序
程序分析:可以利用冒泡排序法,即从后9个比较过程中,选择一个最小的与第一个元素交换, 下次类推,即用第二个元素与后8个进行比较,并进行交换
#include<stdio.h>
#define N 10
int main()
{
int i,j,a[N],temp;
printf("请输入 10 个数字:\n");
for(i=0;i<N;i++)
scanf("%d",&a[i]);
for(i=0;i<N-1;i++)
{
int min=i;
for(j=i+1;j<N;j++)
if(a[min]>a[j]) min=j;
if(min!=i)
{
temp=a[min];
a[min]=a[i];
a[i]=temp;
}
}
printf("排序结果是:\n");
for(i=0;i<N;i++)
printf("%d ",a[i]);
printf("\n");
return 0;
}
输出结果:
请输入 10 个数字:
23 2 27 98 234 1 4 90 88 34
排序结果是:
1 2 4 23 27 34 88 90 98 234
21.有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中
程序分析:首先判断此数是否大于最后一个数,然后再考虑插入中间的数的情况,插入后此元素之后的数,依次后移一个位置。
#include<stdio.h>
int main()
{
int a[11]={1,4,6,9,13,16,19,28,40,100};
int temp1,temp2,number,end,i,j;
printf("原始数组是:\n");
for(i=0;i<10;i++)
printf("%4d",a[i]);
printf("\n插入一个新的数字: ");
scanf("%d",&number);
end=a[9];
if(number>end)
a[10]=number;
else
{
for(i=0;i<10;i++)
{
if(a[i]>number)
{
temp1=a[i];
a[i]=number;
for(j=i+1;j<11;j++)
{
temp2=a[j];
a[j]=temp1;
temp1=temp2;
}
break;
}
}
}
for(i=0;i<11;i++)
printf("%4d",a[i]);
printf("\n");
return 0;
}
输出结果:
原始数组是:
1 4 6 9 13 16 19 28 40 100
插入一个新的数字: 10
1 4 6 9 10 13 16 19 28 40 100
22.将一个数组逆序输出
程序分析:首尾交换。
#include<stdio.h>
#define N 10
int main()
{
int a[N]={0,1,2,3,4,5,6,7,8,9};
int i,t;
printf("原始数组是:\n");
for(i=0;i<N;i++)
printf("%d ",a[i]);
for(i=0;i<N/2;i++)
{
t=a[i];
a[i]=a[N-1-i];
a[N-1-i]=t;
}
printf("\n排序后的数组:\n");
for(i=0;i<N;i++)
printf("%d ",a[i]);
printf("\n");
return 0;
}
输出结果:
原始数组是:
0 1 2 3 4 5 6 7 8 9
排序后的数组:
9 8 7 6 5 4 3 2 1 0
23.有 n个整数,使其前面各数顺序向后移 m 个位置,最后m个数变成最前面的 m 个数
#include <stdio.h>
#include <stdlib.h>
int main()
{
int arr[20];
int i,n,offset;
//输入数组大小和数组内容
printf("Total numbers?\n");
scanf("%d",&n);
printf("Input %d numbers.\n",n);
for(i=0;i<n;i++)
scanf("%d",&arr[i]);
//输入滚动偏移量
printf("Set your offset.\n");
scanf("%d",&offset);
printf("Offset is %d.\n",offset);
//打印滚动前数组
print_arr(arr,n);
//滚动数组并打印
move(arr,n,offset);
print_arr(arr,n);
}
//打印数组
void print_arr(int array[],int n)
{
int i;
for(i=0;i<n;++i)
printf("%4d",array[i]);
printf("\n");
}
//滚动数组
void move(int array[],int n,int offset)
{
int *p,*arr_end;
arr_end=array+n; //数组最后一个元素的下一个位置
int last;
//滚动直到偏移量为0
while(offset)
{
last=*(arr_end-1);
for(p=arr_end-1;p!=array;--p) //向右滚动一位
*p=*(p-1);
*array=last;
--offset;
}
}
24.有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位
#include <stdio.h>
void main()
{
int num[50],n,*p,j,loop,i,m,k;
printf("请输入这一圈人的数量:\n");
scanf("%d",&n);
p=num;
//开始给这些人编号
for (j=0;j<n;j++)
{
*(p+j)=j+1;
}
i=0;//i用于计数,即让指针后移
m=0;//m记录退出圈子的人数
k=0;//k报数1,2,3
while(m<n-1)//当退出的人数不大于总人数时,即留下的人数至少是一个人
//这句不能写成m<n,因为假设有8人,当退出了6人时,此时还是进行人数退出,即m++,
//这时是7<8,剩下的一个人自己喊1,2,3那么他也就退出了,将不会有输出
{
if (*(p+i)!=0)//如果这个人的头上编号不是0就开始报数加1,这里采用的方法是报数为3的人头上编号重置为0
{
k++;
}
if (k==3)
{ k=0; //报数清零,即下一个人从1开始报数
*(p+i)=0;//将报数为3的人编号重置为0
m++; //退出人数加1
}
i++; //指针后移
if (i==n)//这句很关键,如果到了队尾,就要使指针重新指向对头
//并且它只能放在i++后面,因为只有i++了才有可能i==n
{
i=0;
}
}
printf("现在剩下的人是:");
for (loop=0;loop<n;loop++)
{
if (num[loop]!=0)
{
printf("%2d号\n",num[loop]);
}
}
}
输出结果:
请输入这一圈人的数量:
8
现在剩下的人是: 7号
25.创建一个链表
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct LNode{
int data;
struct LNode *next;
}LNode,*LinkList;
LinkList CreateList(int n);
void print(LinkList h);
int main()
{
LinkList Head=NULL;
int n;
scanf("%d",&n);
Head=CreateList(n);
printf("刚刚建立的各个链表元素的值为:\n");
print(Head);
printf("\n\n");
system("pause");
return 0;
}
LinkList CreateList(int n)
{
LinkList L,p,q;
int i;
L=(LNode*)malloc(sizeof(LNode));
if(!L)return 0;
L->next=NULL;
q=L;
for(i=1;i<=n;i++)
{
p=(LinkList)malloc(sizeof(LNode));
printf("请输入第%d个元素的值:",i);
scanf("%d",&(p->data));
p->next=NULL;
q->next=p;
q=p;
}
return L;
}
void print(LinkList h)
{
LinkList p=h->next;
while(p!=NULL){
printf("%d ",p->data);
p=p->next;
}
}
26.反向输出一个链表
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct LNode{
int data;
struct LNode *next;
}LNode,*LinkList;
LinkList CreateList(int n);
void print(LinkList h);
int main()
{
LinkList Head=NULL;
int n;
scanf("%d",&n);
Head=CreateList(n);
printf("刚刚建立的各个链表元素的值为:\n");
print(Head);
printf("\n\n");
system("pause");
return 0;
}
LinkList CreateList(int n)
{
LinkList L,p,q;
int i;
L=(LNode*)malloc(sizeof(LNode));
if(!L)return 0;
L->next=NULL;
q=L;
for(i=1;i<=n;i++)
{
p=(LinkList)malloc(sizeof(LNode));
printf("请输入第%d个元素的值:",i);
scanf("%d",&(p->data));
p->next=NULL;
q->next=p;
q=p;
}
return L;
}
void print(LinkList h)
{
LinkList p=h->next;
while(p!=NULL){
printf("%d ",p->data);
p=p->next;
}
}
27.连接两个链表
#include <stdlib.h>
#include <stdio.h>
struct list
{
int data;
struct list *next;
};
typedef struct list node;
typedef node *link;
link delete_node(link pointer,link tmp)
{
if (tmp==NULL) /*delete first node*/
return pointer->next;
else
{
if(tmp->next->next==NULL)/*delete last node*/
tmp->next=NULL;
else /*delete the other node*/
tmp->next=tmp->next->next;
return pointer;
}
}
void selection_sort(link pointer,int num)
{
link tmp,btmp;
int i,min;
for(i=0;i<num;i++)
{
tmp=pointer;
min=tmp->data;
btmp=NULL;
while(tmp->next)
{
if(min>tmp->next->data)
{
min=tmp->next->data;
btmp=tmp;
}
tmp=tmp->next;
}
printf("\40: %d\n",min);
pointer=delete_node(pointer,btmp);
}
}
link create_list(int array[],int num)
{
link tmp1,tmp2,pointer;
int i;
pointer=(link)malloc(sizeof(node));
pointer->data=array[0];
tmp1=pointer;
for(i=1;i<num;i++)
{
tmp2=(link)malloc(sizeof(node));
tmp2->next=NULL;
tmp2->data=array[i];
tmp1->next=tmp2;
tmp1=tmp1->next;
}
return pointer;
}
link concatenate(link pointer1,link pointer2)
{
link tmp;
tmp=pointer1;
while(tmp->next)
tmp=tmp->next;
tmp->next=pointer2;
return pointer1;
}
int main(void)
{
int arr1[]={3,12,8,9,11};
link ptr;
ptr=create_list(arr1,5);
selection_sort(ptr,5);
}
28.海滩上原来最少有多少个桃子?
题目:海滩上有一堆桃子,五只猴子来分。第一只猴子把这堆桃子平均分为五份,多了一个,这只 猴子把多的一个扔入海中,拿走了一份。第二只猴子把剩下的桃子又平均分成五份,又多了 一个,它同样把多的一个扔入海中,拿走了一份,第三、第四、第五只猴子都是这样做的, 问海滩上原来最少有多少个桃子?
#include<stdio.h>
#include<stdlib.h>
int main()
{
int x
,i=0,j=1;
while(i<5){
x=4*j;
for(i=0;i<5;i++)
{
if(x%4!=0){break;}
x=(x/4)*5+1;
}
j++;
}
printf("%d\n",x);
return 0;
}
输出结果:
3121
29.809*??=800*??+9*?? 其中??代表的两位数, 809*??为四位数,8*??的结果为两位数,9*??的结果为3位数。求??代表的两位数,及809*??后的结果
#include <stdio.h>
void output(long int b, long int i){
printf("\n%ld = 800 * %ld + 9 * %ld\n", b,i,i);
}
int main(){
void output(long int b, long int i);
long int a,b,i;
a = 809;
for(i = 10; i < 100; i++){
b = i * a;
if (b >= 1000 && b <= 10000 && 8 * i < 100 && 9 * i >= 100){
output(b, i);
}
}
return 0;
}
输出结果:
9708 = 800 * 12 + 9 * 12
30.电话号码加密
题目:某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,加密规则如下: 每位数字都加上5,然后用和除以10的余数代替该数字,再将第一位和第四位交换,第二位和第三位交换。
#include <stdio.h>
int main()
{
int a,i,aa[4],t;
printf("请输入四位数字:");
scanf("%d",&a);
aa[0]=a%10;
aa[1]=a%100/10;
aa[2]=a%1000/100;
aa[3]=a/1000;
for(i=0;i<=3;i++)
{
aa[i]+=5;
aa[i]%=10;
}
for(i=0;i<=3/2;i++)
{
t=aa[i];
aa[i]=aa[3-i];
aa[3-i]=t;
}
printf("加密后的数字:");
for(i=3;i>=0;i--)
printf("%d",aa[i]);
printf("\n");
}
输出结果:
请输入四位数字:1234
加密后的数字:9876
31.猜谜游戏
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void caizi(void)
{
int n;
char begin;
int count = 1;
srand((int)time(NULL));
int m = (rand() % 100) + 1;
puts("游戏开始,请输入数字:");
while (1)
{
scanf("%d", &n);
if (n == m)
{
printf("猜中了,使用了 %d 次!\n", count);
if (count == 1)
{
printf("你是神级人物了!膜拜\n");
getchar();
printf("你已经达到最高级别,还需要玩吗?Y/N \n");
scanf("%c", &begin);
if (begin == 'Y' || begin == 'y') //重复玩的一个嵌套循环
{
caizi();
}
else
{
printf("谢谢,再见!\n");
}
}
else if (count <= 5)
{
printf("你是王级人物了!非常赞\n");
getchar();
printf("需要挑战最高级别不?Y/N \n");
scanf("%c", &begin);
if (begin == 'Y' || begin == 'y')
{
caizi();
}
else
{
printf("谢谢,再见!\n");
}
}
else if (count <= 10)
{
printf("你是大师级人物了!狂赞\n");
getchar();
printf("需要挑战最高级别不?Y/N \n");
scanf("%c", &begin);
if (begin == 'Y' || begin == 'y')
{
caizi();
}
else
{
printf("谢谢,再见!\n");
}
}
else if (count <= 15)
{
printf("你是钻石级人物了!怒赞\n");
getchar();
printf("需要挑战最高级别不?Y/N \n");
scanf("%c", &begin);
if (begin == 'Y' || begin == 'y')
{
caizi();
}
else
{
printf("谢谢,再见!\n");
}
}
else
{
getchar();
printf("你的技术还有待提高哦!重玩? Y/N\n");
scanf("%c",&begin);
if (begin == 'Y' || begin == 'y')
{
caizi();
}
else
{
printf("谢谢,再见!\n");
}
}
break;
}
else if (n < m)
{
puts("太小了!");
puts("重新输入:");
}
else
{
puts("太大了!");
puts("重新输入:");
}
count++;//计数器
}
}
int main(void)
{
caizi();
system("pause");
return 0;
}
输出结果:
游戏开始,请输入数字:
50
太大了!
重新输入:
25
太小了!
重新输入:
40
太大了!
重新输入:
30
太大了!
重新输入:
27
太小了!
重新输入:
28
猜中了,使用了 6 次!
你是大师级人物了!狂赞
需要挑战最高级别不?Y/N
N
谢谢,再见!
32.计算字符串中子串出现的次数
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int i,j,k,TLen,PLen,count=0;
char T[50],P[10];
printf("请输入两个字符串,以回车隔开,母串在前,子串在后:\n");
gets(T);
gets(P);
TLen=strlen(T);
PLen=strlen(P);
for(i=0;i<=TLen-PLen;i++)
{
for(j=0,k=i;j<PLen&&P[j]==T[k];j++,k++)
;
if(j==PLen)count++;
}
printf("%d\n",count);
system("pause");
return 0;
}
输出结果:
请输入两个字符串,以回车隔开,母串在前,子串在后:
abca
a
2