当前位置:文档之家› C语言试题

C语言试题

6.9 巧分橘子
一家农户以果园为生,一天,父亲拿出一堆橘子,共2520个,准备分给他的6个儿子。
父亲按事先写在一张纸上的数字把这堆橘子分完,每个人分到的橘子的个数都不相同。
然后他说:“老大,把你分到的橘子分1/8给老二,老二拿到后,连同原来的橘子分1/7给老三,老三拿到后,
连同原来的橘子分1/6给老四,以此类推,最后老六拿到后,连同原来的橘子分1/3给老大,这样,
你们每个人分到的橘子就一样多了。”问兄弟6人原先各分到多少只橘子。 请将兄弟6人的橘子数存储到一维数组中,
并按照下列各式输出(下面只提供格式,数据不准确):
x[1]=111
x[2]=222
x[3]=333
x[4]=444
x[5]=555
x[6]=666
#include<stdio.h>
void main()
{
int a[6],b[6],i;
for(i=0;i<6;i++)
{
a[i]=2520/6;
b[i]=8-i;
}
a[0]=a[0]-(a[5]/(b[5]-1));
for(i=5;i>=1;i--)
{
a[i]=a[i]+(a[i]/(b[i]-1))-(a[i-1]/(b[i-1]-1));
}
a[0]=a[0]*b[0]/(b[0]-1);
for(i=0;i<6;i++)
printf("x[%d]=%d\n",i+1,a[i]);
}
选做题 6.1 大家一起做游戏
幼儿园的小朋友们刚学习了如何数数,阿姨在下课时组织大家一起玩游戏。规则如下:所有的小朋友绕成一圈,顺序排号,
从第一个小朋友开始报数,
凡是报到固定数字(例如5)的,都退出该游戏,
直到只剩下一位小朋友游戏才中止。
每个小朋友都希望自己能有更多的练习数数的机会,所以都希望成为最终被留下的那位。
现在,请大家帮小朋友们计算一下,在第一次排号的时候排到第几位才能成为最终被留下的小朋友。
输入:小朋友的个数(<=50),要被练习的数字
输出:最终被留下的小朋友的序号
说明:如“要被练习的数字”是5,则每次数到5的同学要退出该游戏
#include<stdio.h>
void main()
{
int N,n,i,s=0,a;
scanf("%d%d",&N,&n);
for(i=2;i<=N;i++)
s=(s+n)%i;
a=s+1;
printf("The left child is NO %d.\n",a);
}
选做题6.2 猜数字
有如下一组数字,其中每个数字都在 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<stdio.h>
#include<math.h>
void main()
{
int i,sum=0;
do
{
scanf("%d",&i);
sum=sum+pow(2,i-1);
}while(i!=0);
printf("%d\n",sum);
}
选做题 6.3 小蜜蜂
一只小蜜蜂在如下图所示的蜂窝上爬行。它爬行时,只能从一个格爬到相邻的大号格子中。例如,
从 1 号格子可以爬到 2 号或者 3 号格子,
从 2 号则可以爬到 3 号或者 4 号格子。
请问从一个格子 a 爬到一个格子 b 一共有多少种可行的路线。
输入:分别是起始点 a 和终止点 b 的编号。( a 和 b 在 1~100 之间,且 a<b 。)
输出:可行的路线数目
#include<stdio.h>
void main()
{
int a,b,x,i;
int f[100];
f[1]=1;f[2]=2;
scanf("%d%d",&a,&b);
x=b-a;
if(x==1)
printf("%d\n",f[1]);
if(x==2)
printf("%d\n",f[2]);
if(x>=3)
{
for(i=3;i<=x;i++)
f[i]=f[i-1]+f[i-2];
printf("%d\n",f[x]);
}
}
选做题 6.4 数制转换
我们通常使用的都是十进制的数字,但其实在生活中也经常会使用其它进制。
这个题目会给你两个不同的数字,它们不属于同一进制,要求你计算出当它们分别处于何种进制之中时,两个数字相等。
譬如 12 和 5 ,在十进制下它们是不等的,但若 12 使用 3 进制而 5 使用六进制或十进制时,它们的值就是相等的。
因此只要选择合适的进制, 12 和 5 就可以是相等的。
程序的输入是两个数字 M 和 N( 其十进制的值不超过 1000000000) ,它们的进制在 2~36 之间。对于十以下的数字,
用 0~9 表示,而十以上的数字,则使用大写的 A~Z 表示。
求出分别在 2~36 哪种进制下 M 和 N 相等。若相等则输出相应的进制,若不等则输出错误信息。信息的格式见测试用例。
#define N 50
#include"string.h"
#include"stdio.h"
int main()
{
char a[N],b[N],d[N],e[N],d0[N];
int i,j,o,r,g,h,w,t,l,k,max1,max2;
double p[N],q[N]={0},u[N],v[N]={0},c[N],f[N],m,n;
for(i=0;i<N;i++)
{
scanf("%c",&a[i]);
if(a[i]=='\x20')
{
l=i; break;
}
}
gets(d);
if(d[0]!='\x20')
{k=strlen(d);
goto C;}
if(d[0]=='\x20')
{
strcpy(d0,d);
g=strlen(d0);
for(i=0;d0[i]=='\x20';i++);
j=i;
for(i=0;i<g-j;i++)
d[i]=d0[i+j];
k=g-j;
}
C:for(i=0;i<l;i++)
{
b[i]=a[l-i-1];
if(b[i]<='\x39'&&b[i]>='\x30') c[i]=b[i]-'0';
if(b[i]<='\x5A'&&b[i]>='\x41') c[i]=b[i]-'7'; }
for(i=0;i<k;i++)
{e[i]=d[k-i-1];
if(e[i]<='\x39'&&e[i]>='\x30') f[i]=e[i]-'0';
if(e[i]<='\x5A'&&

;e[i]>='\x41') f[i]=e[i]-'7'; }
max1=c[0];
for(i=1;i<l;i++)
{
if(max1<c[i]) max1=c[i];
}
if(max1==0) max1=1;
max2=f[0];
for(i=1;i<k;i++)
{
if(max2<f[i]) max2=f[i];
}

if(max2==0) max2=1;
for(i=max1+1;i<=36;i++)
{
for(j=0;j<l;j++)
{
m=c[j];
for(g=0;g<j;g++)
{
m=m*i;
}
q[i]=q[i]+m;
}
}
for(i=max2+1;i<=36;i++)
{
for(j=0;j<k;j++)
{
n=f[j];
for(g=0;g<j;g++)
{
n=n*i;
}
v[i]=v[i]+n;
}
}
for(g=max1+1;g<=36;g++)
for(h=max2+1;h<=36;h++)
{
if(q[g]==v[h])
{
w=g,t=h;
goto out;
}
}
for(i=0;i<l;i++)
printf("%c",a[i]);
printf(" is not equal to ");
for(i=0;i<k;i++)
printf("%c",d[i]);
printf(" in any base 2..36\n");
goto outs;
out:for(i=0;i<l;i++)
printf("%c",a[i]);
printf(" (base %d) = ",w);
for(i=0;i<k;i++)
printf("%c",d[i]);
printf(" (base %d)\n",t);
outs:;
}
选做题 6.5 等值数列段
如果一个数列中的某一段(至少有两个元素)的各元素值均相同,则称之为等值数列段。
等值数列段中元素的个数叫做等值数列段的长度。
输入:由N个元素组成的整数数列A(其中N<=50)
输出:A中长度最大的等值数列段的始末位置,如果没有等值数列段,则输出No equal number list.
说明:始末位置是指数组下标,即0表示第一个元素。
如果有多个同等长度的等值数列,只输出第一个等值数列的起始位置。
当在一个LIST中出现两个等长的连续串的时候,我们的答案应该是第一个等长串。
#include<stdio.h>
void main()
{
int a[50];
int f[10]={0};
int n,i,j,k=-1,t,q,s,o,o1,count=1,max=-1;
scanf("%d",&n);
for(i=0;i<=n-1;i++)
scanf("%d",&a[i]);
do{
for(j=0;j<=n-1;j++)
{
if(a[j]==a[j+1])
{
count=count+1;
k=count;
f[j+1]=f[j+1]+k;
}
if(a[j]!=a[j+1])
{
count=1;
continue;
}
max=k;
}
}while(max<k);
if(max==-1)
printf("No equal number list.\n");
//for(q=0;q<=n-1;q++)
//printf("%d ",f[q]);
//printf("\n");
else{
o=f[0];
for(s=1;s<=n-1;s++)
{
if(f[s]>o)
{
o=f[s];
o1=s;
}
}
//printf("%d %d",o1,o);
//printf("\n");
printf("The longest equal number list is from %d to %d.\n",o1-o+1,o1);
}
}
选做6.6 邮票组合
背景:我们寄信都要贴邮票,在邮局有一些小面值的邮票,通过这些小面值邮票中的一张或几张的组合,
可以满足不同邮件的不同的邮资。
现在,邮局有4种不同面值的邮票。在每个信封上最多能贴5张邮票,面值可相同,可不同。
输入:四种邮票的面值。
输出:用这四种面值组成的邮资最大的从1开始的一个连续的区间。
说明:如结果为10,则表明使用4张邮票可组合出1、2、

3、4、5、6、7、8、9、10这些邮资。
名词解释:

资:就是你寄东西需要花多少钱。
邮票面额:是由国家发行的具有固定价格的花纸片,被称为邮票。
如果你寄东西,邮局称了重量,告诉你要240分。这样你就要贴邮票了。
如果现在邮局的邮票有面值为80分、50分、20分和10分的四种,你就可以采用不同的组合得到240的邮资,
例如:采用3张80分的可以凑出240分;或者24张10分的凑起来240分也可以。显然不同邮票的组合都可以得到同样一种邮资。
#include<stdio.h>
int neng(int a[],int max)
{
int i,j,k,m,n;
int sum;
for(i=0;i<5;i++)
for(j=0;j<5;j++)
for(k=0;k<5;k++)
for(m=0;m<5;m++)
for(n=0;n<5;n++)
{
sum=a[i]+a[j]+a[k]+a[m]+a[n];
if (sum==max)
return 1;
}
return 0;
}
void main()
{
int a[5],i;
int max=0;
a[4]=0;
scanf("%d%d%d%d",&a[0],&a[1],&a[2],&a[3]);
while(1)
{
if(neng(a,max))
{
max++;
}
else break;
}
printf("The max is %d.\n",max-1);
}
选做6.7 十进制数转换为16位二进制数
将任一正整数(<65536)转换为 16 位二进制形式。
输入: 正整数
输出: 正整数的 16 位二进制数
友情提示:定义一个整型数组,数组有16个元素,保存变换后的二进制数。
#include<stdio.h>
void main()
{
int n,i;
int a[16];
scanf("%d",&n);
if(n>0&&n<65536)
{
for(i=0;i<=15;i++)
{
a[i]=n%2;
n=n/2;
}
for(i=15;i>=0;i--)
printf("%d",a[i]);
printf("\n");
}
else
printf("Invalid input!\n");
}
选做题6.9 折半插入排序
排序是程序设计中的重要内容之一,据不完全统计,在一般的数据处理程序中,排序占去了处理机时间的四分之一,而在典型的安装程序中,一半以上的时间用在对表的排序上。
常用的排序算法有:直接插入排序,折半插入排序,希尔排序,起泡排序,快速排序,选择排序,堆排序等。其中直接插入排序的基本操作是将一个记录插入到已排好序的有序表中,从而得到一个新的、记录数增1的有序表。在直接插入排序中,为了找到插入位置,采用了顺序查找的方法。为了提高查找速度,可以采用折半查找,这种排序称折半插入排序。
折半查找法先取有序数组的中间元素与查找值相比较。如相等则查找成功;如查找值大于中间元素,则再取高半部的中间元素与查找值相比较。如查找值小于中间元素,则再取低半部的中间元素与查找值相比较。如此重复直到查找成功或最终未找到该数为止。在折半插入排序算法中,由于进行关键字比较的次数比较少,所以算法的效率就比较高。
例如:有序列10,90,80,30,20,15。我们进行折半插入排

序的过程如下:
初始(第1趟):有序子序列为空。待排序数
据为10,则不需要进行关键字比较,直接插入。
第2趟:有序子序列为“10”,待排序数据为90,进行1次比较就可以确定插入位置,得到长度+1的有序子序列“10,90”。此时比较次数为 1 。
第2趟:有序子序列为“10,90”。待排序数据为80,取有序序列中间(取整)的元素10进行第 1 次比较,80大;则应该从“90”这个子序列中进行折半插入80,进行第 2 次比较,定位应该的插入位置,得到有序序列“10,80,90”。此趟比较次数为 2。
第3趟:有序子序列为“10,80,90”。待排序数据为30,取有序序列中间的元素80进行第 1 次比较,30小;则应该从“10”这个子序列中进行折半插入30,进行第 2 次比较,可以定位应该插入的位置,得到新的长度+1的有序子序列。此趟比较次数为 2。
第4趟:有序子序列为“10,30,80,90”。待排序数据为20,取有序序列中间的元素30进行第 1 次比较,20小;则应该从“10”这个子序列中进行折半插入20,进行第 2 次比较,可以确定应该插入的位置。此趟比较次数为 2。
第5趟:有序子序列为“10,20,30,80,90”。待排序数据为15,取有序序列中间的元素30进行第 1 次比较,15小;则应该从“10,20”这个子序列中进行折半插入15,取子序列中间的元素10,进行第 2 次比较,15大,则应该从“20”这个子序列中进行折半插入排序,再进行 1 次比较就可以确定应该插入的位置。此趟比较次数为 3。
此时,完成排序,得到升序序列“10,15,20,30,80,90”。在整个排序过程中进行关键字比较的总次数 = 0+1+2+2+2+3 = 10。
输入:数列中元素个数(元素数量<=100)
数列
输出:使用折半插入排序后的有序升序数列
在折半插入排序过程中进行关键字比较的次数
说明:输出个数列之间用空格分隔
#include <stdio.h>
int main(){
int n,a[100],b[100],i,j,count=0,lengthb=1;
scanf("%d\n",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
b[0]=a[0];
for(i=1;i<n;i++){
int c=0,d=lengthb-1,flag=0;
do {
if(a[i]>b[(c+d)/2]){ //待插入数字大于中间值
c=(c+d)/2+1;
count++;
}
else {
if(a[i]<b[(c+d)/2]){ //待插入数字小于中间值
d=(c+d)/2-1;
count++;
}
else {
count++;
flag=1;
break;
}
}
}
while(c<=d);
//处理最后一个数字
if(flag==0){
for(j=i-1;j>=c;j--){
b[j+1]=b[j];
}

b[c]=a[i];
lengthb++;
}
}
for(i=0;i<lengthb;i++){
printf("%d",b[i]);
if(i!=lengthb-1)printf(" ");
}
printf(&quo

t;\n%d\n",count);
return 0;
}
8.1 合并字符串
输入两个已经按从小到大顺序排列好的字符串,编写一个合并两个字符串的函数,使合并后的字符串,仍然是从小到 大排列。
输入:两个已经排好顺序(升序)的两个字符串
输出:一个合并在一起的有序(升序)的字符串
要求:设计一个效率尽量高的算法,对每个字符串只扫描一遍就可以了。
如果采用先进行串连接,然后再进行排序的算法,则效率太低了。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char a[100],b[100],t;
int k,i,j;
gets(a);
gets(b);
strcat(a,b);
k=strlen(a);
for(j=1;j<=k;j++)
for(i=0;i<k-j;i++)
if(a[i]>=a[i+1])
{
t=a[i];
a[i]=a[i+1];
a[i+1]=t;
}
puts(a);
return 0;
}
8.3 删除重复字符
背景:
输入一个长度不超过 100 的字符串,删除串中的重复字符。
输入:
输入要检查的字符串,长度不超过100个字符。例如:abacaeedabcdcd。
输出:
删除重复字符后的字符串。例如:abced。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char a[100],b[100];
int n,i,j,cnt=1;
gets(a);
n=strlen(a);
b[0]=a[0];
for(i=1;i<n;i++)
{
for(j=0;j<i;j++)
{
if(a[i]==a[j])
break;
}
if(a[i]==a[j]&&i==j)
{
b[cnt]=a[i];
cnt++;
}
}
for(i=0;i<cnt;i++)
printf("%c",b[i]);
printf("\n");
return 0;
}
8.4 删除字符串中指定字符
输入两个字符串 s1 和 s2 ,在 s1 中删除任何 s2 中有的字符。例如, s1 :“ abc123ad ”, s2 :“ a1 ” ,则输出“bc23d ”。
输入: 两个字符串 s1 和 s2
输出: 删除后的字符串 s1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char a[100],b[100],c[100];
int x,y,i,j,cnt;
scanf("%s",a);
scanf("%s",b);
x=strlen(b);
y=strlen(a);
for(j=0;j<x;j++)
{
cnt=0;
for(i=0;i<y;i++)
if(a[i]!=b[j])
{
c[cnt]=a[i];
cnt++;
}
strcpy(a,c);
y=cnt;
}
for(i=0;i<cnt;i++)
printf("%c",c[i]);
printf("\n");
return 0;
}
8.5 单词有多少
用空格或换行分开的字符串称为单词。输入多行字符串,直到遇到了单词 "stop" 时才停止。最后输出单词的数量。用于分割单词的空格或换行可能多于1个。
输入: 多个字符串
输出: 单
词的数量
#include <stdio.h>
#include <malloc.h>
#include <string.h>
void main()
{
int count=0;
char *word ;
while(1)
{
word=(char *) malloc (sizeof(char)*20);
scanf("%s",word);
++count;
if(0==strcmp(word,"stop"))
break;
free(word);
}
printf("%d\n",count-1);
}
8.6 在指定位置插入字符串
输入

两个字符串 s1 、 s2 和 s1 中任意字符 k ,在 s1 中的指定字符 k 第一次出现的位置处插入字符串 s2 并输出。
输入: 两个字符串 s1 、 s2 和 s1 中任意字符 k
输出: 插入后的字符串 s1
#include<stdio.h>
#include<string.h>
void main()
{
char s1[100],s2[100],s3[100];
char c;
int i,j,n,t,count=-1;
gets(s1);
gets(s2);
n=strlen(s1);
t=strlen(s2);
scanf("%c",&c);
for(i=0;i<=n-1;i++)
{count=count+1;
if(c==s1[i])
break;}
for(i=0;i<count;i++)
s3[i]=s1[i];
for(i=count;i<count+t;i++)
s3[i]=s2[i-count];
for(i=count+t;i<=n+t;i++)
s3[i]=s1[i-t];
puts(s3);
/*for(i=0;i<q;i++)
{
printf("%c",s3[i]);
}
printf("\n");*/
}
选做T 8.1 拱猪计分
背景:拱猪是一种很有趣的扑克牌游戏。即使你不知道它的玩法,你也可以由它的计分方式来了解它的趣味性。 假设在此我们仅考虑四个人的拱猪牌局,本题要求你根据下面的计分规则,在牌局结束时计算四位玩家所得分数。
我们分别以S、H、D及C来代表黑桃,红心,方块及梅花,并以数字1至 13来代表A、2、…、Q、K等牌点,例如:H1为红心A,S13为黑桃K。
牌局结束时,由各玩家持有的有关计分的牌(计分牌)仅有S12(猪),所有红心牌,D11(羊)及C10(加倍)等16张牌。其它牌均弃置不计。若未持有这16张牌之任一张则以得零分计算。
若持有C10的玩家只有该张牌而没有任何其它牌则得+50分,若除了C10 还有其它计分牌,则将其它计分牌所得分数加倍计算。
若红心牌不在同一家,则H1至H13等13张牌均以负分计,其数值为-50, -2,-3,-4,-5,-6,-7,-8,-9,-10,-20,-30,-40。而且S12与D11分别以-100及+100分计算。
若红心牌H1至H13均在同一家,有下列情形:
所有红心牌以+200分计算。
若S12、D11皆在吃下所有红心牌之一家,则此玩家得+500分。
而C10还是以前面所述原则计算之。
例一:若各玩家持有计分牌如下: ( 每行代表一玩家所持有之牌 )
S12 H3 H5 H13
D11 H8 H9
C10 H1 H2 H4 H6 H7
H10 H11 H12

则各家之得分依序为: -148 、 +83 、 -138 及 -60 。
例二:若各玩家持有计分牌如下:(第四家未持有任何计分牌)
H1 H2 H3 H4 H5 H6 H7 H8 H9 H10 H11 H12 H13
S12 C10
D11
则各家之得分依序为: +200 、 -200 、 +100 及 0 。
例三:若有一玩家持有所有 16 张计分牌,则得 +1000
分。其余三家均得零分。
输入:每个输入文件由多组测试数据构成,每组测试数据有四行,每一行第一个数为该玩家所持有计分牌总数,而后列出其所持有之所有计分牌,牌数与各计分牌均以一个以上的空格分开。相邻两组测试数据之间不会有空白行,读到四家持牌数都为 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;
}
选作T 8.2 合并果子
在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。
每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。
因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类
数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。
例如有3种果子,数目依次为1,2,9。可以先将1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。所以多多总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。
输入:输入包括两行,第一行是一个整数n(1<=n<=10000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1<=ai<=10000)是第i种

果子的数目。

输出: 输出包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于231。
#include<stdio.h>
#include<string.h>
#include<math.h>
void main()
{
int i,j,k,t,n,sum=0;
int a[10]={0};
int b[10]={0};
char s[10][100];
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%s",s[i]);
for(t=1;t<=n;t++)
a[t]=strlen(s[t]);
for(i=1;i<=n;i++)
for(j=0;j<a[i];j++)
s[i][j]=s[i][j]-48;
for(j=1;j<=n;j++)
{
for(i=0;i<=a[j]/2-1;i++)
{
t=s[j][i];
s[j][i]=s[j][a[j]-1-i];
s[j][a[j]-1-i]=t;
}
}
for(j=1;j<=n;j++)
{
for(i=0;i<=a[j];i++)
{
b[j]=b[j]+s[j][i]*pow(10,i);
}
}
for(j=1;j<=n-1;j++)
for(i=1;i<=n-j;i++)
{
if(b[i]>b[i+1])
{
t=b[i];
b[i]=b[i+1];
b[i+1]=t;
}
}
sum=(n-1)*(b[1]+b[2]);
for(i=2;i<=n-1;i++)
sum=sum+(n-i)*b[i+1];
printf("%d\n",sum);
}
选作T 8.3 安全的密码
随着电子设备的广泛运用,密码也渐渐融入每个人的生活。保护好密码,不仅关系到个人隐私,更关系到个人的财产和安全。一个安全的密码,最好由大小写字母、数字或符号组成。包含越多种类的字符,其安全性就越高。同时密码还需要有一定的长度,通常至少要由六个以上的字符组成。
并不是每个人都喜欢这样复杂的密码,很多人在设置密码的时候,喜欢使用自己的名字或者生日,但这是很大的安全隐患。
任务
小林正在设计一个网络交易系统,为了保证用户的密码安全,他需要一个程序,判断用户自己设置的密码是否安全,如果不安全,则给出提示。现在他向你求助,请你帮忙设计一个程序来解决这个问题。
应当按照以下的规则来判断密码是否安全:
如果密码长度小于 6 位,则不安全
如果组成密码的字符只有一类,则不安全
如果组成密码的字符有两类,则为中度安全
如果组成密码的字符有三类或以上,则为安全
通常,可以认为数字、大写字母、小写字母和其它符号为四类不同的字符。
输入:输入的第一行
是一个整数 N,表明后面有多少组密码。随后的 N 行输入包括 N 个密码,每个密码的长度均小于 20 个字符。
输出:针对每一个密码判断并输出它是否安全。对于不安全的密码输出 "Not Safe",对于中度安全的密码输出 "Medium Safe",对于安全的密码输出 "Safe"
输入样例
41234abcdefABC1231#c3Gh输出样例
Not SafeNot SafeMedium SafeSafe
#include<stdio.h>
#include<string.h>
void main()
{
int n,i,j,k,t,flag1=0,flag2=0,flag3=0,flag4=0;
char s[20][50];
scanf("%d",&n);
for(i=0;i<=n;i++)
gets(s[i]);
for(i=1;i<=n;i++)
{
t=strlen(s[i]);
if(t<6)
printf("Not Safe\n");
if

(t>=6)
{
for(flag1=0,flag2=0,flag3=0,flag4=0,j=0;s[i][j]!='\0';j++)
{
if(s[i][j]>=48&&s[i][j]<=57)
flag1++;
if(s[i][j]>=65&&s[i][j]<=90)
flag2++;
if(s[i][j]>=97&&s[i][j]<=122)
flag3++;
if((s[i][j]>=33&&s[i][j]<=47&&s[i][j]>=58&&s[i][j]<=64&&s[i][j]>=91&&s[i][j]<=96&&s[i][j]>=123&&s[i][j]<=126)||(s[i][j]==' '))
flag4++;
}
if(flag1==t||flag2==t||flag3==t||flag4==t)
printf("Not Safe\n");
if((flag1*flag2>0&&flag3==0&&flag4==0)||(flag1*flag3>0&&flag2==0&&flag4==0)||(flag1*flag4>0&&flag2==0&&flag3==0)||(flag2*flag3>0&&flag1==0&&flag4==0)||(flag2*flag4>0&&flag3==0&&flag1==0)||(flag3*flag4>0&&flag1==0&&flag2==0))
printf("Medium Safe\n");
if((flag1*flag2*flag3>0&&flag4==0)||(flag1*flag2*flag4>0&&flag3==0)||(flag1*flag4*flag3>0&&flag2==0)||(flag4*flag2*flag3>0&&flag1==0)||(flag1*flag2*flag3*flag4>0))
printf("Safe\n");
}
}
}
选作T 8.4 扫雷
背景 :你玩儿过扫雷游戏吧?有个操作系统中带了这个小游戏,那个系统叫什么来着?在游戏中要想过关,就必须要在一个 NxM 的区域上找出所有的地雷。游戏过程中,计算机会在地图上显示一些数字从而帮助你确定哪里有地雷。例如,在下面这个有两颗地雷的 4x4 的地图(*表示地雷):
*........*...... 根据上面的地图,可以计算出应该提供给游戏者的数字如下所示:
*10022101*101110 每个数字表示了该方格周围到底有几个地雷,当然,一个方格周围最多的时候只会有八个。
输入 :输入中将包括一系列的地图,每个地图的第一行有两个整数 n 和 m(0 <n,m <= 100),它们表示了地图的行数和列数。下面的 n 行每行都有 m 个字符,其中 "." 表示安全而 "*" 表示地雷。如果地图的 n 和 m 都为 0,则表示输入结束。
输出 :针对每一个地图,首先输出一行:
Field #x:其中 x 是当前地图的编号(从 1 开始)。下面的 n 行则将地图中的 "." 以数字表示,该数字表示该方格周围有多少颗地雷。
#include<stdio.h>
#include<string.h>
#include<stdlib
.h>
# define N 9
void main()
{
int i,j,k,t=1,x1,x2;
int n[100],m[100];
char c[100][100][100];
char s[100][100][100];
for(k=1;k<=N;k++)
{
scanf("%d%d",&n[k],&m[k]);
if(n[k]==0&&m[k]==0)
break;
t++;
for(j=0;j<n[k];j++)
{
scanf("%s",&c[k][j]);
}
for(j=0;j<n[k];j++)
for(i=0;i<m[k];i++)
s[k][j][i]='0';
for(j=0;j<n[k];j++)
{
for(i=0;i<m[k];i++)
{
if(c[k][j][i]=='*')
{
s[k][j

][i]=c[k][j][i];
}
}
}
for(j=0;j<n[k];j++)
{
for(i=0;i<m[k];i++)
{
if(c[k][j][i]=='*')
{
s[k][j][i]=c[k][j][i];
if(j==0&&i==0)
{
for(x1=0;x1<=1;x1++)
for(x2=0;x2<=1;x2++)
if(s[k][j+x1][i+x2]!='*')
{
s[k][j+x1][i+x2]++;
}
}
if(j==0&&i>0)
{
for(x1=0;x1<=1;x1++)
for(x2=-1;x2<=1;x2++)
if(s[k][j+x1][i+x2]!='*')
{
s[k][j+x1][i+x2]++;
}
}
if(i==0&&j>0)
{
for(x1=-1;x1<=1;x1++)
for(x2=0;x2<=1;x2++)
if(s[k][j+x1][i+x2]!='*')
{
s[k][j+x1][i+x2]++;
}
}
if(i>0&&j>0)
{
for(x1=-1;x1<=1;x1++)
for(x2=-1;x2<=1;x2++)
if(s[k][j+x1][i+x2]!='*')
{
s[k][j+x1][i+x2]++;
}
}
}
}
}
}
for(k=1;k<=t-1;k++)
{
printf("Field #%d:\n",k);
for(j=0;j<n[k];j++)
{
for(i=0;i<m[k];i++)
printf("%c",s[k][j][i]);
printf("\n");
}
if(k!=t-1)
printf("\n");
}
}
选作T8.5 身份证的奥秘
背景18位身份证标准在国家质量技术监督局于1999年7月1日实施的GB11643-1999《公民身份号码》中做了明确的规定。 GB11643-1999《公民身份号码》为GB11643-1989《社会保障号码》的修订版,其中指出将原标准名称"社会保障号码"更名为"公民身份号码",另外GB11643-1999《公民身份号码》从实施之日起代替GB11643-1989。GB11643-1999《公民身份号码》主要内容如下:
一、范围
该标准规定了公民身份号码的编码对象、号码的结构和表现形式,使每个编码对象获得一个唯一的、不变的法定号码。
二、编码对象
公民身
份号码的编码对象是具有中华人民共和国国籍的公民。
三、号码的结构和表示形式
1、号码的结构
公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
2、地址码
表示编码对象常住户口所在县(市、旗、区)的行政区划代码,按GB/T2260的规定执行。
3、出生日期码
表示编码对象出生的年、月、日,按GB/T7408的规定执行,年、月、日代码之间不用分隔符。
4、顺序码
表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。
5、校验码
(1)十七位数字本体码加权求和公式
S = Sum(Ai * Wi), i = 0, ... , 16 ,先对前17位数字的权求和
Ai: 表示第i位置上的身份证号码数字值
Wi: 表示第i位置上的加权因子
Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2
(2)计算模
Y = mod(S, 11)
(3)通过模得到对应的校验码
Y: 0 1 2 3 4 5 6 7 8 9 10
校验码: 1 0 X 9 8 7 6 5 4 3 2
四、举例如下:

京市朝阳区: 110105************
广东省汕头市: 440524188001010014
15位的身份证号升级办法:
15位的身份证号:dddddd yymmdd xx p
18位的身份证号:dddddd yyyymmdd xx p y
其中dddddd为地址码(省地县三级)
yyyymmdd yymmdd 为出生年月日
xx顺号类编码
p性别
15 位的 yy 年升为 18 位后,变成 19yy年,但对于百岁以上老人, 则为 18yy 年,此时,他们的最后三位顺序码为996, 997, 998 或 999 来标记。
输入
输入n组身份证号码,第一行为个数,以后每行为身份证号码。
输出
如果输入的身份证号码为15位,则将其升级为18位后显示输出;否则判断其是否为合法身份证号,并逐行输出
#include<stdio.h>
#include<string.h>
void main()
{
int Wi[17]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
char yan[11]={'1','0','X','9','8','7','6','5','4','3','2'};
int i,j,k,n,sum=0,Y=0,q,sum1=0,Y1=0;
int t[20];
char s[10][19];
char b[10][19];
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%s",s[i]);
for(i=1;i<=n;i++)
t[i]=strlen(s[i]);
for(k=1;k<=n;k++)
{
if(t[k]==18)
{
Y=0;
sum=0;
for(i=0;i<=17;i++)
s[k][i]=s[k][i]-48;
//for(Y=0,sum=0,i=1;i<=n;i++)
//{
for(j=0;j<=16;j++)
sum=sum+s[k][j]*Wi[j];
Y=sum%11;
// }
for(j=0;j<=17;j++)
s[k][j]=s[k][j]+48;
if(s[k][17]==yan[Y])
printf("Valid\n");
if(s[k][17]!=yan[Y])
printf("Invalid\n");
}
if(t[k]==15)
{
Y1=0;
sum1=0;
for(q=0;q<=5;q++)
b[k][q]=s[k][q];
if(s[k][
12]=='9'&&s[k][13]=='9')
{
b[k][6]='1';
b[k][7]='8';
}
if(s[k][12]!='9'||s[k][13]!='9')
{
b[k][6]='1';
b[k][7]='9';
}
for(q=6;q<=14;q++)
{
b[k][q+2]=s[k][q];
}
for(j=0;j<=16;j++)
b[k][j]=b[k][j]-48;
//for(i=1;i<=n;i++)
//{
for(j=0;j<=16;j++)
sum1=sum1+b[k][j]*Wi[j];
Y1=sum1%11;
// }
for(j=0;j<=16;j++)
b[k][j]=b[k][j]+48;
b[k][17]=yan[Y1];
for(j=0;j<=17;j++)
printf("%c",b[k][j]);
printf("\n");
}
}
}
9.1 数的合并
请编写函数fun,其功能是:将两个两位数的正整数a、b合并形成一个整数放在c中。合并的方式是:将a的十位和个位依次存放在c数的十位和千位上,b的十位和个位依次存放在c数的个位和百位上。
例如:当a=45,b=12,调用该函数后,c=5241。
部分源程序如下,只需要完成fun函数的编写即可。
#include <stdio.h>
int fun(int a,int b)
{//只需要完成此函数的功能即可
}
int main()
{
int a,b,c;
scanf("%d%d",&a,&b);
c=fun(a,b);
printf("c=%d\n",c);
}

#include <stdio.h>
int fun(int a,int b)
{ int c,d;
d=a%10;
a=a/10;
c=d*1000+a*10;
d=b%10;
b=b/10;
c=c+b+d*100;

return c;
}
int main()
{
int a,b,c;
scanf("%d%d",&a,&b);
c=fun(a,b);
printf("c=%d\n",c);
}
9.2 素数的判断
请编写函数fun,其功能是判断一个整数n是否为素数,如果是素数,则返回1,否则返回0。
部分源程序给出如下,请勿改动主函数main和其他函数,仅在函数fun的花括号中填入所编写的代码即可。
#include <stdio.h>
int fun(int n)
{//仅需要在此完成函数的功能即可
}
int main()
{
int a;
scanf("%d",&a);
if(fun(a)) printf("Prime\n");
else printf("Non Prime\n");
}
#include <stdio.h>
int fun(int n)
{
int i,flag=0;
for(i=2;i<n;i++)
{ if(n%i==0)
flag++;
}
if(flag==0)
return 1;
if(flag>0)
return 0;
}
int main()
{
int a;
scanf("%d",&a);
if(fun(a)) printf("Prime\n");
else printf("Non Prime\n");
}
9.3 求级数
请编写函数fun,它的功能是计算下列级数和,值由函数值返回。
例如,当n=10,x=0.3时,函数值为1.349859。
请勿改动主函数main,仅在函数fun的花括号中填入所编写的若干语句。
#include <stdio.h>
double fun(double x,int n)
{
}
int main()
{
double x;
int n;
scanf("%lf%d",&x,&n);
printf("%lf\n",fun(x,n));
}
#include <stdio.h>
#include <math.h>
double n1(int n)
{
double sum1=1;
int j;
for(j=1;j<=n;j++)
sum1=sum1*j;
return(sum1);
}
double fun(double x,int n)
{
double sum=1;

int i;
for(i=1;i<=n;i++)
sum=sum+pow(x,i)/n1(i);
return sum;
}
int main()
{
double x;
int n;
scanf("%lf%d",&x,&n);
printf("%lf\n",fun(x,n));
}
9.4 求大于m且紧靠m的k个素数
请编写一个函数,其功能是:将大于整数m且紧靠m的k个素数存入xx所指的数组中。
例如,若输入17 5,则应输出19 23 29 31 37
请勿改动主函数main,仅在函数fun的花括号中填入所编写的若干语句。
#include <stdio.h>
void fun(int m,int k,int xx[])
{
}
int main()
{
int m,n,zz[1000];
scanf("%d%d",&m,&n);
fun(m,n,zz);
for(m=0;m<n;m++)
printf("%6d",zz[m]);
printf("\n");
return 0;
}
#include <stdio.h>
#include <math.h>
void fun(int m,int k,int xx[])
{
int i,j,t=0,n;
for(i=m+1;;i++)
{
n=sqrt(i);
for(j=2;j<=n;j++)
if(i%j==0)
break;
if(j>=n+1)
{
xx[t]=i;
t++;
}
if(t==k)
break;
}
}
int main()
{
int m,n,zz[1000];
scanf("%d%d",&m,&n);
fun(m,n,zz);
for(m=0;m<n;m++)
printf("%6d",zz[m]);
printf("\n");
return 0;
}
9.5 删除指定字符
请编写函数fun,其功能是:从字符串中删除指定的字符。同一字母的大、小写按照不同的字符处理。
部分源程序给出如下:
#inc

lude <stdio.h>
void fun(char s[],char c)
{
}
int main()
{
char str[80];
char ch;
gets(str);
scanf("%c",&ch);
fun(str,ch);
printf("%s\n",str);
return 0;
}
#include <stdio.h>
#include<string.h>
void fun(char s[],char c)
{
int i,t,j;
t=strlen(s);
for(i=0;i<t;i++)
if(s[i]==c)
for(j=i;j<t;j++)
s[j]=s[j+1];
}
int main()
{
char str[80];
char ch;
gets(str);
scanf("%c",&ch);
fun(str,ch);
printf("%s\n",str);
return 0;
}
9.6 杀鸡用牛刀——学习递归喽
背景:哈哈!我们终于学了递归了,现在大家一定感到非常有意思吧,那个典型的“汉诺塔”问题,一个非常短的程序居然可以完成如此复杂的工作,真是神奇啊!来吧,让我们也动手编写一个递归程序,当然,我们要编写的不可能太复杂。
功能:求整数 n 到 m 区间的累加和,其中n<=m。
输入:区间的起始点n 区间的终止点m
输出:累加和
要求:使用递归算法完成。
#include <stdio.h>
#include<string.h>
int fun(int i,int j)
{
int sum=0,t;
for(t=i;t<=j;t++)
sum=sum+t;
return(sum);
}
int main()
{
int i,j;
scanf("%d%d",&i,&j);
printf("%d\n",fun(i,j));
return 0;
}
9.7 求最大公约数——递归
请使用递归算法计算正整数n和m的最大公约数GCD(n,m)。
输入:n和m
输出:n和m的最大公约数
#include<stdio.h>
int f(int n,int m)
{
int i;
if(m<=n&&n%m==0)
i=m;
if(n<m)
i=f(m,n);
if(m<=n&&n%m!=0)
i=f(m,n%m);

return i;
}
void main()
{
int n,m;
scanf("%d%d",&n,&m);
printf("%d\n",f(n,m));
}
9.8 求数列的第N项
已知整数数列第一项和第二项是1,该数列从第三项开始,如果该项是奇数项,则它是前两项之和,如果该项是偶数项,则它是前两项之差,即:
f( n ) = 1 当 n = 1 或 2 时,
f( n ) = f( n-1 ) - f( n-2 ) 当n是偶数时,
f( n ) = f( n-1 ) + f( n-2 ) 当n是奇数时,
编写一个递归函数,求数列的第N项。
#include<stdio.h>
int f(int n)
{
int sum;
int i;
if(n==1||n==2)
i=1;
if(n>2&&n%2==0)
{
i=f(n-1)-f(n-2);
}
if(n>2&&n%2!=0)
{
i=f(n-1)+f(n-2);
}
return(i);
}
void main()
{
int n,i;
scanf("%d",&n);
printf("%d\n",f(n));
}
9.9 偶数分解
编写程序,输入若干个大于2的正整数,如果是偶数,则将其分解为两个素数并输出;如果输入的奇数,则输出“××× is odd number!” ;输入为0时程序结束。只有1和它本身这两个因数的自然数叫做素数,0和1既不是素数也不是和数。
实现分解的过程用函数实现。
输入:整数序列,0
输出:偶数1 = 素数A + 素数B (当输入是偶数时)
奇数1 is odd number! (当输入是奇

数时)
#include<stdio.h>
#include<stdlib.h>
int ss(int n)
{
int i,t;
for(i=2;i<n;i++)
if(n%i==0)
{t=0;
break;}
if(i>=n)
t=1;
return(t);
}
void fun(int q)
{
int k;
if(q%2!=0)
printf("%d is odd number!\n",q);
if(q%2==0)
{
for(k=2;k<q;k++)
{
if(ss(k)==1&&ss(q-k)==1)
{
printf("%d=%d+%d\n",q,k,q-k);
break;
}
}
}
}
int main()
{
int a[100],i,k=1,count,q;
for(i=0;k!=0;i++)
{
scanf("%d",&k);
a[i]=k;
}
count=i-2;
for(i=0;i<=count;i++)
{
q=a[i];
fun(q);
}
return 0;
}
9.10 子串反序--递归
请编写一个递归函数 reverse(char str[], int start, int end ) ,该函数的功能是将串 str 中下标从 start 开始到 end 结束的字符颠倒顺序。假设 start 和 end 都在合理的取值范围。
例如:
执行前:str[]="0123456";start=1 ;end=4
执行后:strr[]="0432156"
要求在该函数中不使用新的数组,没有循环。
#include <stdio.h>
void reverse(char str[], int start, int end )
{//请完成此函数
}
int main( )
{ char str[100];
int start, end;
gets(str);
scanf("%d%d", &start, &end);
reverse( str, start, end );
printf("%s\n", str);
return 0;
}
#include <stdio.h>
void reverse(char str[], int start, int end )
{
int i,j=0;
for(i=0;i<=(end-start-1)/2;i++)
{j=str[start+i];
str[start+i]=str[end-i];
str[end-i]=j;}
}
int main()
{ char str[100];
int start, end;
gets(str);
scanf("%d%d", &start, &end);
reverse
( str, start, end );
printf("%s\n", str);
return 0;
}
7.1 数的合并
请编写函数fun,其功能是:将两个两位数的正整数a、b合并形成一个整数放在c中。合并的方式是:将a的十位和个位依次存放在c数的十位和千位上,b的十位和个位依次存放在c数的个位和百位上。
例如:当a=45,b=12,调用该函数后,c=5241。
部分源程序如下,只需要完成fun函数的编写即可。
#include <stdio.h>
void fun(int a,int b,int *c)
{//只需要完成此函数的功能即可
}
int main()
{
int a,b,c;
scanf("%d%d",&a,&b);
fun(a,b,&c);
printf("%d\n",c);
}
#include <stdio.h>
void fun(int a,int b,int *c)
{
*c=(a/10)*10+(a%10)*1000+(b/10)*1+(b%10)*100;
}
int main()
{
int a,b,c;
scanf("%d%d",&a,&b);
fun(a,b,&c);
printf("%d\n",c);
}
7.2 数组中奇偶数
请编一个函数 fun(int *a,int n,int *odd,int *even) ,函数的功能是分别求出数组中所有奇数之和以及所有偶数之和。形参 n 给了数组中数据的个数:利用指针 odd 返回奇数之和,利用指针 even 返回偶数之和。
例如:数组中的值依次为: 1 , 8 , 2 , 3 , 11 , 6 ;则利用指针 odd 返回奇数之和 15 ;利用指针 even 返回偶数之和 16


部分程序源码如下。
#include <stdio.h>
#define N 20
void fun(int *a,int n,int *odd,int *even)
{ //只需要完成此处代码即可
}
int main()
{ int a[N],i,n,odd,even;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
fun(a,n,&odd,&even);
printf("The sum of odd numbers:%d\n",odd);
printf("The sum of even numbers:%d\n",even);
return 0;
}
#include <stdio.h>
#define N 20
void fun(int *a,int n,int *odd,int *even)
{
int i;
int *p;
*odd=0;*even=0;
for(p=a,i=0;i<n;i++)
{
if(*(p+i)%2==0)
*even=*even+*(p+i);
if(*(p+i)%2!=0)
*odd=*odd+*(p+i);
}
}

int main()
{ int a[N],i,n,odd,even;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
fun(a,n,&odd,&even);
printf("The sum of odd numbers:%d\n",odd);
printf("The sum of even numbers:%d\n",even);
return 0;
}
7.3 浮点数四舍五入
请编一个函数 void fun(double a,double *h) ,函数的功能是对变量 h 中的值保留 2 位小数,并对第三位进行四舍五入(规定 h 中的值为正数)。
例如: h 值为 8.32433 ,则函数返回 8.32 ;
h 值为 8.32533 ,则函数返回 8.33 。
部分程序源码如下。
#include <stdio.h>
void fun(double a,double *h)
{//只需要完成此函数的功能即可
}
int main( )
{
double a,h;
scanf("%lf",&a);
fun(a,&h);
printf("The result:%lf\n",h);
return 0;
}
#include <stdio.h>
void fun(double a,double *h)
{//只需要完成此函数的功能即可
int i,t;
t=(int)(a*1000);
if(t%10<5)
*h=((double)((int)(a*100)))/100;
if(t%10>=5)
*h=((double)((i
nt)(a*100)+1))/100;
}
int main()
{
double a,h;
scanf("%lf",&a);
fun(a,&h);
printf("The result:%lf\n",h);
return 0;
}
7.4 字符移动
请编一个函数void fun(char *s) ,函数的功能是把字符串中所有的字符前移一个位置,串中的第一个字符移到最后。
例如:原有的字符串为: Mn.123xyZ ,则调用该函数后,串中的内容为: n.123xyZM 。
部分程序源码如下:
#include <stdio.h>
#define N 81
void fun(char *s)
{ // 只需要完成此处代码即可
}
int main( )
{ char a[N];
gets(a);
fun(a);
printf("%s\n",a);
}
#include <stdio.h>
#define N 81
void fun(char *s)
{ // 只需要完成此处代码即可
char *p,t;
t=*s;
p=s+1;
for(;*s!='\0';s++,p++)
*s=*p;
*(s-1)=t;
}
int main()
{ char a[N];
gets(a);
fun(a);
printf("%s\n",a);
}
7.5 生成新数
给定程序中,函数fun的功能是:将形参n所指变量中,各位上为偶数的数去除,剩余的数按原来从高位到低位的顺序组成一个新的数,并通过形参指针n传回所指变量。
例如,输入一个数:27638496,新的数:为739。


部分源程序如下:
#include <stdio.h>
void fun(int *n)
{ //只需要完成此部分功能即可
}
int main( )
{ int n=-1;
while(n>99999999||n<0)
{ scanf("%ld",&n); }
fun(&n);
printf("%d\n",n);
return 0;
}
#include <stdio.h>
#include<math.h>
void fun(int *n)
{ //只需要完成此部分功能即可
int a[10],b[10];
int p=0;
int i,j=0,t,k,r,count=0;
for(i=0;*n!=0;i++)
{
a[i]=*n%10;
*n=*n/10;
count++;
}
//printf("%d\n",count);
//for(k=0;k<count;k++)
//printf("%d",a[k]);
//printf("\n");
for(i=0;i<=count-1;i++)
{
if(a[i]%2!=0)
{
b[j]=a[i];
j++;
}
}
//printf("%d\n",j);
//for(t=0;t<=j-1;t++)
//printf("%d",b[t]);
//printf("\n");
for(r=j-1;r>=0;r--)
{
p=p+b[r]*pow(10,r);
}
*n=p;
}
int main()
{ int n=-1;
while(n>99999999||n<0)
{ scanf("%ld",&n); }
fun(&n);
printf("%d\n",n);
return 0;
}
7.6 字符串转换成整数
请编写一个函数fun,它的功能是:将一个数字字符串转换为一个整数。例如,若输入字符串"-1234",则函数把它转换为整数值 -1234。函数fun中给出的语句仅供参考。
部分源程序如下:
#include <stdio.h>
#include <string.h>
int fun ( char *p)
{ //只需要完成此处功能即可
}
int main() /* 主函数 */
{ char s[6];
int n;
gets(s);
n = fun(s);
printf("%d\n",n);
return 0;
}
#include <stdio.h>
#include <string.h>
#include <math.h>
int fun (char *p)
{ //只需要完成此处功能即可
int i,n=0,flag=0,j=0,t,k;
int a[10];
for(i=0;*(p+i)!='\0';i++)
{
if(*p=='-')
flag=1;
if(*(p+i)>='0'&&*(p+i)<='9')

{
a[j]=*(p+i)-48;
j++;
}
}
//printf("%d\n",j);
//for(k=0;k<=j-1;k++)
//printf("%d",a[k]);
//printf("\n");
for(t=0;t<=j-1;t++)
{
n=n+a[t]*pow(10,j-1-t);
}
n=n*pow(-1,flag);
return(n);
}
int main() /* 主函数 */
{ char s[6];
int n;
gets(s);
n=fun(s);
printf("%d\n",n);
return 0;
}
7.7 二维数组按列优先存放
请编写函数fun, 函数的功能是: 将M行N列的二维数组中的字符数据, 按列的顺序依次放到一个字符串中。
例如, 二维数组中的数据为:
W W W W
S S S S
H H H H
则字符串中的内容应是: WSHWSHWSHWSH。
部分源程序如下:
#include <stdio.h>
#define M 3
#define N 4
void fun(char s[][N], char *b)
{ //只需要完成此部分功能即可
}
int main()
{ char a[100],w[M][N]={{'W','W','W','W'},{'S','S','S','S'},{'H','H','H','H'}};
fun(w,a);
puts(a);
return 0;
}
#include <stdio.h>
#define M 3
#define N 4
voi

d fun(char s[][N],char *b)
{ //只需要完成此部分功能即可
int i,j,t=0,k,q;
char c[12];
for(j=0;j<100;j++)
{
*(b+j)=0;
}
for(j=0;j<=3;j++)
for(i=0;i<=2;i++)
{
c[t]=s[i][j];
t++;
}
//for(k=0;k<t;k++)
//printf("%c",c[k]);
//printf("\n");
for(q=0;q<t;q++)
{
*(b+q)=c[q];
}
}
int main()
{ char a[100],w[M][N]={{'W','W','W','W'},{'S','S','S','S'},{'H','H','H','H'}};
fun(w,a);
puts(a);
return 0;
}
选做T 7.1 数组元素移动
请编写函数fun, 函数的功能是: 移动一维数组中的内容; 若数组中有n个整数, 要求把下标从0到p(含p,p小于等于n-1)的数组元素平移到数组的最后。 例如, 一维数组中的原始内容为: 1,2,3,4,5,6,7,8,9,10; p的值为3。移动后, 一维数组中的内容应为: 5,6,7,8,9,10,1,2,3,4。
部分源程序如下:
#include <stdio.h>
#define N 80
void fun(int *w, int p, int n)
{ //只需要完成此部分功能即可
}
int main( )
{
int a[N]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
int i,p,n=15;
scanf("%d",&p);
fun(a,p,n);
for(i=0; i<n; i++)
printf("%3d",a[i]);
printf("\n");
return 0;
}
#include <stdio.h>
#define N 80
void fun(int *w, int p, int n)
{ //只需要完成此部分功能即可
int i,j=0;
int b[N],a[15];
for(i=0;i<=14;i++)
a[i]=*(w+i);
for(i=p+1;i<=14;i++)
{
b[j]=a[i];
j++;
}
for(i=0;i<j;i++)
*(w+i)=b[i];
for(i=0;i<=p;i++)
*(w+j+i)=a[i];
}
int main( )
{
int a[N]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
int i,p,n=15;
scanf("%d",&p);
fun(a,p,n);
for(i=0; i<n; i++)
printf("%3d",a[i]);
printf("\n");
return 0;
}
选做T 7.2 字符串匹配
给定程序中函数fun的功能是: 计算s所指字符串中含有t所指字符串的数目, 并作为函数值
返回。
请改正函数fun中指定部位的错误, 使它能得出正确的结果。只能改 /*********found**********/ 的下一行。
注意: 不要改动main函数, 不得增行或删行, 也不得更改程序的结构。
给定源程序:
#include <stdio.h>
#include <string.h>
#define N 80
int fun(char *s, char *t)
{ int n;
char *p , *r;
n=0;
while ( *s )
{ p=s;
/*********found**********/
r=p;
while(*r)
if(*r==*p) { r++; p++; }
else break;
/*********found**********/
if(*r= 0)
n++;
s++;
}
return n;
}
int main()
{
char a[N],b[N]; int m;
gets(a);
gets( b );
m=fun(a, b);
printf("m=%d\n",m);
return 0;
}
#include <stdio.h>
#include <string.h>
#define N 80
int fun(char *s, char *t)
{ int n;
char *p , *r;
n=0;
while ( *s )
{ p=s;
/*********found**********/
r=t;
while(*r)
if(*r==*p) { r++; p++; }
else break;
/*********found**********/
if(*r=='\0

')
n++;
s++;
}
return n;
}
int main()
{
char a[N],b[N]; int m;
gets(a);
gets( b );
m=fun(a, b);
printf("m=%d\n",m);
return 0;
}
选做T 7.3 形成新的字符串
给定程序MODI1.C中函数fun的功能是: 将s所指字符串中位于奇数位置的字符或ASCII码为偶数的字符放入t所指数组中(规定第一个字符放在第0位中)。
例如, 字符串中的数据为: AABBCCDDEEFF,
则输出应当是:ABBCDDEFF。
请改正函数fun中指定部位的错误, 使它能得出正确的结果。 只能修改/***********found**********/ 的下一行。
注意: 不要改动main函数, 不得增行或删行, 也不得更改程序的结构!
给定源程序如下:
#include <stdio.h>
#include <string.h>
#define N 80
void fun(char *s, char t[])
{
int i, j=0;
for(i=0; i<strlen(s); i++)
/***********found**********/
if(i%2 && s[i]%2==0)
t[j++]=s[i];
/***********found**********/
t[i]='\0';
}
int main( )
{ char s[N], t[N];
gets(s);
fun(s, t);
printf("%s\n",t);
}
#include <stdio.h>
#include <string.h>
#define N 80
void fun(char *s, char t[])
{
int i, j=0;
for(i=0; i<strlen(s); i++)
/***********found**********/
if(i%2 || s[i]%2==0)
t[j++]=s[i];
/***********found**********/
t[j]='\0';
}
int main( )
{ char s[N], t[N];
gets(s);
fun(s, t);
printf("%s\n",t);
}
文件填空1
给定程序中,函数fun的功能是将形参给定的字符串、整数、浮点数写到文本文件中,再用字符方式从此文本文件中逐个读入并显示在终端屏幕上。
请在程序的下划线处填入正确的内容并把下划线删除, 使程序得出正确的结果。
不得增行或删行,也不得更改程序的结构,只能更改/**********found**********/ 的下一行!
给定源程序如下:
#include <stdio.h>
void fun(char *s, int a,
double f)
{
/**********found**********/
__1__ fp;
char ch;
fp = fopen("file1.txt", "w");
fprintf(fp, "%s %d %f\n", s, a, f);
fclose(fp);
fp = fopen("file1.txt", "r");
ch = fgetc(fp);
/**********found**********/
while (!feof(__2__)) {
/**********found**********/
putchar(__3__); ch = fgetc(fp); }
fclose(fp);
}
int main()
{ char a[10]="Hello!"; int b=12345;
double c= 98.76;
fun(a,b,c);
return 0;
} #include <stdio.h>
void fun(char *s, int a, double f)
{
/**********found**********/
FILE *fp;
char ch;
fp = fopen("file1.txt", "w");
fprintf(fp, "%s %d %f\n", s, a, f);
fclose(fp);
fp = fopen("file1.txt", "r");
ch = fgetc(fp);
/**********found**********/
while (!feof(fp)) {
/**********found**********/
putchar(ch); ch = fgetc(fp); }
fclose(fp);
}
int main()
{ char a[10]="Hello!"; int b=12345;
double c= 9

8.76;
fun(a,b,c);
return 0;
}
文件填空2
程序通过定义学生结构体变量,存储了学生的学号、姓名和3门课的成绩。所有学生数据均以二进制方式输出到文件中。函数fun的功能是重写形参filename所指文件中最后一个学生的数据,即用新的学生数据覆盖该学生原来的数据,其它学生的数据不变。
请在程序的下划线处填入正确的内容并把下划线删除, 使程序得出正确的结果。
不得增行或删行,也不得更改程序的结构!
给定源程序:
#include <stdio.h>
#define N 5
typedef struct student {
long sno;
char name[10];
float score[3];
} STU;
void fun(char *filename, STU n)
{ FILE *fp;
/**********found**********/
fp = fopen(__1__, "rb+");
/**********found**********/
fseek(__2__, -1L*sizeof(STU), SEEK_END);
/**********found**********/
fwrite(&n, sizeof(STU), 1, __3__);
fclose(fp);
}
int main()
{ STU t[N]={ {10001,"MaChao", {91, 92, 77}}, {10002,"CaoKai", {75, 60, 88}},
{10003,"LiSi", {85, 70, 78}}, {10004,"FangFang", {90, 82, 87}},
{10005,"ZhangSan", {95, 80, 88}} };
STU n={ 10006,"ZhaoSi", {55, 70, 68} }, ss[N];
int i,j; FILE *fp;
fp = fopen("student.dat", "wb");
fwrite(t, sizeof(STU), N, fp);
fclose(fp);
fp = fopen("student.dat", "rb");
fread(ss, sizeof(STU), N, fp);
fclose(fp);
fun("student.dat", n);
printf("The data after modifing :");
fp = fopen("student.dat", "rb");
fread(ss, sizeof(STU), N, fp);
fclose(fp);
for (j=0; j<N; j++)
{ printf("\nNo: %ld Name: %-8s Scores: ",ss[j].sno, ss[j].name);
for (i=0; i<3; i++) printf("%.2f ", ss[j].score[i]);
}
printf("\n");
return 0;
}
#include <stdio.h>
#define N 5
typedef struct student {
long sno;
char name[10];
float score[3];
} STU;
void fun(char *filename, STU n)
{ FILE *fp;
/**********found**********/
fp = fopen(filename, "rb+");
/**********found**********/
fseek(fp, -1L*sizeof(STU), SEEK_END);
/**********found**********/
fwrite(&n,
sizeof(STU), 1, fp);
fclose(fp);
}
int main()
{ STU t[N]={ {10001,"MaChao", {91, 92, 77}}, {10002,"CaoKai", {75, 60, 88}},
{10003,"LiSi", {85, 70, 78}}, {10004,"FangFang", {90, 82, 87}},
{10005,"ZhangSan", {95, 80, 88}} };
STU n={ 10006,"ZhaoSi", {55, 70, 68} }, ss[N];
int i,j; FILE *fp;
fp = fopen("student.dat", "wb");
fwrite(t, sizeof(STU), N, fp);
fclose(fp);
fp = fopen("student.dat", "rb");
fread(ss, sizeof(STU), N, fp);
fclose(fp);
fun("student.dat", n);
printf("The data after modifing :");
fp = fopen("student.dat", "rb");
fread(ss, s

相关主题
相关文档 最新文档