北理C语言作业及答案2.docx
《北理C语言作业及答案2.docx》由会员分享,可在线阅读,更多相关《北理C语言作业及答案2.docx(31页珍藏版)》请在冰豆网上搜索。
北理C语言作业及答案2
34北理工的恶龙
成绩:
10/折扣:
0.8
背景:
最近,北理工出现了一只恶龙,它长着很多头,而且还会吐火,它将会把北理工烧成废墟,于是,校长下令召集全校所有勇士杀死这只恶龙。
要杀死这只龙,必须把它所有的头都砍掉,每个勇士只能砍一个龙头,龙的每个头大小都不一样,一个勇士只有在身高不小于龙头的直径的情况下才能砍下它。
而且勇士们要求,砍下一个龙头必须得到和自己身高厘米数一样的学分。
校长想花最少的学分数杀死恶龙,于是找到你寻求帮助。
输入:
第一行龙头数n,勇士人数m(1<=n,m<=100)接下来n行,每行包含一个整数,表示龙头的直径接下来m行,每行包含一个整数,表示勇士的身高l
输出:
如果勇士们能完成任务,输出校长需要花的最小费用;否则输出“bitisdoomed!
”
测试输入
期待的输出
时间限制
内存限制
额外进程
测试用例1
以文本方式显示
1.23↵
2.5↵
3.4↵
4.7↵
5.8↵
6.4↵
以文本方式显示
1.11↵
1秒
64M
0
测试用例2
以文本方式显示
1.21↵
2.5↵
3.5↵
4.10↵
以文本方式显示
1.bitisdoomed!
↵
1秒
64M
0
#include
voidmain()
{
ints=0,t,i,j,m,n,a[100],b[100],c[100];
for(i=0;i<=99;i++)
a[i]=0,b[i]=0,c[i]=0;
scanf("%d%d",&m,&n);
for(i=0;i<=m-1;i++)
scanf("%d",&a[i]);
for(i=0;i<=n-1;i++)
scanf("%d",&b[i]);
if(m>n)
printf("bitisdoomed!
\n");
else
{
for(i=0;i<=m-1;i++)
for(j=i;j<=m-1;j++)
{if(a[i]>a[j])
{t=a[i],a[i]=a[j],a[j]=t;}}
for(i=0;i<=n-1;i++)
for(j=i;j<=n-1;j++)
{if(b[i]>b[j])
{t=b[i],b[i]=b[j],b[j]=t;}}
t=0;
for(i=0;i<=m-1;i++)
for(j=0;j<=n-1;j++)
if(a[i]<=b[j])
{c[t]=b[j];
t++;
b[j]=0;
break;}
if(tprintf("bitisdoomed!
\n");
else
{for(i=0;i<=t;i++)
s=s+c[i];
printf("%d\n",s);}
}
}
35杀鸡用牛刀——要用递归啊!
成绩:
5/折扣:
0.8
背景:
哈哈!
我们终于学了递归了,现在大家一定感到非常有意思吧,那个典型的“汉诺塔”问题,一个非常短的程序居然可以完成如此复杂的工作,真是神奇啊!
来吧,让我们也动手编写一个递归程序,当然,我们要编写的不可能太复杂。
功能:
求整数n到m区间的累加和,其中n<=m。
输入:
区间的起始点n区间的终止点m
输出:
累加和
要求:
使用递归算法完成。
如此简单的题目当然要有隐含的测试用例啦,就3个,看看谁能猜出来。
测试输入
期待的输出
时间限制
内存限制
额外进程
测试用例1
以文本方式显示
1.110↵
以文本方式显示
1.Thesumfrom1to10is55.↵
1秒
64M
0
测试用例2
以文本方式显示
1.1015↵
以文本方式显示
1.Thesumfrom10to15is75.↵
1秒
64M
0
#include
intsum(intm,intn)
{
inti;
if(n==m)
i=n;
else
i=n+sum(m,n-1);
return(i);
}
voidmain()
{
intm,n;
scanf("%d%d",&m,&n);
printf("Thesumfrom%dto%dis%d.\n",m,n,sum(m,n));
}
H13:
安全的密码(选做)
成绩:
5/折扣:
0.8
随着电子设备的广泛运用,密码也渐渐融入每个人的生活。
保护好密码,不仅关系到个人隐私,更关系到个人的财产和安全。
一个安全的密码,最好由大小写字母、数字或符号组成。
包含越多种类的字符,其安全性就越高。
同时密码还需要有一定的长度,通常至少要由六个以上的字符组成。
并不是每个人都喜欢这样复杂的密码,很多人在设置密码的时候,喜欢使用自己的名字或者生日,但这是很大的安全隐患。
任务
林晓炜正在设计一个网络交易系统,为了保证用户的密码安全,他需要一个程序,判断用户自己设置的密码是否安全,如果不安全,则给出提示。
现在他向你求助,请你帮忙设计一个程序来解决这个问题。
应当按照以下的规则来判断密码是否安全:
1.如果密码长度小于6位,则不安全
2.如果组成密码的字符只有一类,则不安全
3.如果组成密码的字符有两类,则为中度安全
4.如果组成密码的字符有三类或以上,则为安全
通常,可以认为数字、大写字母、小写字母和其它符号为四类不同的字符。
输入
输入的第一行是一个整数N,表明后面有多少组密码。
随后的N行输入包括N个密码,每个密码的长度均小于20个字符。
输出
针对每一个密码判断并输出它是否安全。
对于不安全的密码输出"NotSafe",对于中度安全的密码输出"MediumSafe",对于安全的密码输出"Safe"
输入样例
4
1234
abcdef
ABC123
1#c3Gh
输出样例
NotSafe
NotSafe
Medium
SafeSafe
测试输入
期待的输出
时间限制
内存限制
额外进程
测试用例1
以文本方式显示
1.10↵
2.abcDEF↵
3.ABC↵
4.qw↵
5.`↵
6.ABCDEFGHIJKLMNOPQRST↵
7.17890↵
8.1aB↵
9.1B↵
10.aX↵
11.qwe123%^&ABC↵
以文本方式显示
1.MediumSafe↵
2.NotSafe↵
3.NotSafe↵
4.NotSafe↵
5.NotSafe↵
6.NotSafe↵
7.Safe↵
8.NotSafe↵
9.Safe↵
10.Safe↵
1秒
64M
0
#include
#include
charcheck(chars[])
{
intstrlength;
strlength=strlen(s);
intn[4]={0,0,0,0};
intkind=0,i;
if(strlength<6)return'n';//notsafe
else
{
for(i=0;i{
if(s[i]>='0'&&s[i]<='9')n[0]++;
elseif(s[i]>='A'&&s[i]<='Z')n[1]++;
elseif(s[i]>='a'&&s[i]<='z')n[2]++;
elsen[3]++;
}
for(i=0;i<4;i++)
if(n[i]!
=0)kind++;
if(kind==1)return'n';//notsafe
if(kind==2)return'm';//MediumSafe
return's';//Safe
}
}
voidmain()
{
intN,i;
charlevel;
scanf("%d\n",&N);
charstr[50];
for(i=0;i{
gets(str);
level=check(str);
switch(level)
{
case'n':
printf("NotSafe\n");break;
case'm':
printf("MediumSafe\n");break;
case's':
printf("Safe\n");break;
}
}
}
H14:
身份证的奥秘(选做)
成绩:
5/折扣:
0.8
背景
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:
7910584216379105842
(2)计算模
Y=mod(S,11)
(3)通过模得到对应的校验码
Y:
012345678910
校验码:
10X98765432
四、举例如下:
北京市朝阳区:
广东省汕头市:
15位的身份证号升级办法:
15位的身份证号:
ddddddyymmddxxp
18位的身份证号:
ddddddyyyymmddxxpy
∙其中dddddd为地址码(省地县三级)
∙yyyymmddyymmdd为出生年月日
∙xx顺号类编码
∙p性别
15位的yy年升为18位后,变成19yy年,但对于百岁以上老人,则为18yy年,此时,他们的最后三位顺序码为996,997,998或999来标记。
输入
输入n组身份证号码,第一行为个数,以后每行为身份证号码。
输出
如果输入的身份证号码为15位,则将其升级为18位后显示输出;否则判断其是否为合法身份证号,并逐行输出。
测试输入
期待的输出
时间限制
内存限制
额外进程
测试用例1
以文本方式显示
1.4↵
2.↵
3.↵
4.↵
5.↵
以文本方式显示
1.Invalid↵
2.Valid↵
3.↵
4.↵
1秒
64M
0
#include
#include
voidshengji(charstr[])
{
intn=strlen(str);//n=15
charnewstr[19];
inti;
for(i=0;i<6;i++)
{
newstr[i]=str[i];//前六位地址码(省地县三级)
}
for(i=8;i<17;i++)//newstr中的到第位
{
newstr[i]=str[i-2];
}
newstr[6]='1';
chartemp[4];
temp[0]=str[12];
temp[1]=str[13];
temp[2]=str[14];
temp[3]='\0';
if(strcmp(temp,"996")==0||strcmp(temp,"997")==0||strcmp(temp,"998")==0||strcmp(temp,"999")==0)
{
newstr[7]='8';
}
elsenewstr[7]='9';
//下面是校检码,0的ascii码值是
intWi[17]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};//权重
intS=0;
for(i=0;i<17;i++)
{
S=S+Wi[i]*((int)(newstr[i])-48);
}
inty;
y=S%11;
switch(y)
{
case0:
newstr[17]='1';break;
case1:
newstr[17]='0';break;
case2:
newstr[17]='X';break;
case3:
newstr[17]='9';break;
case10:
newstr[17]='2';break;
default:
newstr[17]=(char)(12-y+48);break;
}
newstr[18]='\0';
strcpy(str,newstr);
}
intIscheckedValid(charstr[])
{
intn=strlen(str);//n=18
intnum[17];//保存前位
inti;
for(i=0;i<17;i++)//保存前位
num[i]=(int)str[i]-48;
//下面是校检码,0的ascii码值是
intWi[17]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};//权重
intS=0;
for(i=0;i<17;i++)
{
S=S+Wi[i]*num[i];
}
inty;
y=S%11;
charlastnum;
switch(y)
{
case0:
lastnum='1';break;
case1:
lastnum='0';break;
case2:
lastnum='X';break;
case3:
lastnum='9';break;
case10:
lastnum='2';break;
default:
lastnum=(char)(12-y+48);break;
}
if(lastnum==str[17])
return1;
else
return0;//0表示不合法
}
voidrun(charstr[])
{
intn=strlen(str);
if(n==15)
{
shengji(str);
printf("%s\n",str);
}
elseif(n==18)
{
if(!
IscheckedValid(str))
printf("Invalid\n");
elseprintf("Valid\n");
}
elseprintf("Invalid\n");
}
voidmain()
{
intn;
scanf("%d\n",&n);
charstr[25];
for(inti=0;i{
gets(str);
run(str);
}
}
36科学记数法
成绩:
10/折扣:
0.8
对于非常大或者非常小的数据,我们通常用科学记数法来表示。
例如在科技文献和电脑中经常遇到的2.3×106(计算机中的科学记数法表示为:
2.3E6),或者9.18×10-5(科学记树法表示:
9.18E-5)这种类型的数据。
输入:
用科学记数法表示的数据。
即为符合C语言表示的科学记数法表示。
输出:
该数据的双精度表示
说明:
输入数据的精度不高于小数点后50位。
输入数据时,在实数和幂之间有空格进行分隔,空格个数不定。
结果保留到小数点后8位,如不足8位用0补足,超过8位则截断,不进行四舍五入的处理。
测试输入
期待的输出
时间限制
内存限制
额外进程
测试用例1
以文本方式显示
1.1.2345E3↵
以文本方式显示
1.1234.↵
1秒
64M
0
测试用例2
以文本方式显示
1.1.2345e-3↵
以文本方式显示
1.0.00123450↵
1秒
64M
0
测试用例3
以文本方式显示
1.2.89e20↵
以文本方式显示
1.89123.↵
1秒
64M
0
测试用例4
以文本方式显示
1.1E0↵
以文本方式显示
1.1.00000000↵
1秒
64M
0
测试用例6
以文本方式显示
1.2.7890E1↵
以文本方式显示
1.22.↵
1秒
64M
0
#include"stdio.h"
intmain()
{
intp=-1,n,i=0,j,sign=0,flag=0;charc,s[100];
while(scanf("%c",&c)&&c!
='e'&&c!
='E')
if(c=='.')p=i-1;
elseif(c<='9'&&c>='0')s[i]=c,i++;
elseif(c=='-')sign=1;
elseif(p<0)p=i-1;
for(j=i;j<=60;j++)
s[j]='0';
scanf("%d",&n);
p+=n;
if(sign)printf("-");
if(p<0)
{
p=-p-1;
printf("0.");
for(i=1;i<=p&&i<=8;i++)
printf("0");
for(i=1;i<=8-p;i++)
printf("%c",s[i-1]);
}
else
{
i=0;
while(i<=p)
{
if(s[i]=='0'&&!
flag&&i
else{flag=1;printf("%c",s[i++]);}
}
printf(".");
for(j=1;j<=8;j++)
printf("%c",s[i++]);
}
printf("\n");
return0;
}
37大数分解
成绩:
5/折扣:
0.8
2007级在“计算机科学导论”的期末考试中有一道试题。
下面请你看看那题目应该如何编写。
从键盘输入的一个大于1的整数,通过算法将该整数分解为若干因子的乘积。
输入:
一个正整数。
输出:
分解后的各个因子。
测试输入
期待的输出
时间限制
内存限制
额外进程
测试用例1
以文本方式显示
1.24↵
以文本方式显示
1.2↵
2.2↵
3.2↵
4.3↵
1秒
64M
0
测试用例2
以文本方式显示
1.17↵
以文本方式显示
1.17↵
1秒
64M
0
测试用例3
以文本方式显示
1.15↵
以文本方式显示
1.3↵
2.5↵
1秒
64M
0
测试用例4
以文本方式显示
1.3↵
以文本方式显示
1.3↵
1秒
64M
0
#include
voidmain()
{intn,i;
scanf("%d",&n);
for(i=2;n>1;){
if(n%i==0){
printf("%d\n",i);n/=i;
}
elsei++;
}
}
38回文字符串——递归
成绩:
5/折扣:
0.8
有一种特殊形式的字符串,其正反序相同,被称为“回文字符串”。
例如LeveL就是一个回文字符串。
输入:
字符串
输出:
Yes或者No
说明:
如输出Yes,说明输入的字符串是一个回文字符串
输出No,说明输入的字符串不是一个回文字符串
请使用递归算法实现。
测试输入
期待的输出
时间限制
内存限制
额外进程
测试用例1
以文本方式显示
1.LeveL↵
以文本方式显示
1.Yes↵
1秒
64M
0
#include
#include
intfun(charstr[],inta,intb)
{
if(str[a]!
=str[b])return0;
else
if(a==b||a+1==b&&str[a+1]==str[b])return1;
else
if(str[a]==str[b])return1&&fun(str,a+1,b-1);
}
voidmain()
{
charstr[100];
scanf("%s",str);
intn;
n=strlen(str);
switch(fun(str,0,n-1))
{
case1:
printf("Yes\n");break;
case0:
printf("No\n");break;
}
}
39求最大公约数——递归
成绩:
5/折扣:
0.8
请使用递归算法计算正整数n和m的最大公约数GCD(n,m)。
=m当m<=n且nmodm=0
GCD(N,M)=GCD(m,n)当n=GCD(m,nmodm)其他
输入:
n和m
输出:
n和m的最大公约数
测试输入
期待的输出
时间限制