北理C语言作业及问题详解2.docx
- 文档编号:6375191
- 上传时间:2023-01-05
- 格式:DOCX
- 页数:32
- 大小:34.50KB
北理C语言作业及问题详解2.docx
《北理C语言作业及问题详解2.docx》由会员分享,可在线阅读,更多相关《北理C语言作业及问题详解2.docx(32页珍藏版)》请在冰豆网上搜索。
北理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(t printf("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.890↵ 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 四、举例如下: 市区: X 省市: 4 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.1↵ 3.X↵ 4.1002↵ 5.1996↵ 以文本方式显示 1.Invalid↵ 2.Valid↵ 3.X↵ 4.5↵ 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.50000000↵ 1秒 64M 0 测试用例2 以文本方式显示 1.1.2345e-3↵ 以文本方式显示 1.0.00123450↵ 1秒 64M 0 测试用例3 以文本方式显示 1.2.123456789e20↵ 以文本方式显示 1.9123.45678900↵ 1秒 64M 0 测试用例4 以文本方式显示 1.1E0↵ 以文本方式显示 1.1.00000000↵ 1秒 64M 0 测试用例6 以文本方式显示 1.2.90E1↵ 以文本方式显示 1.22.34567890↵ 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的最大公约数 测试输入 期待的输出 时间限制 存限制 额外进程 测试用例1 以文本方式显示
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 北理 语言 作业 问题 详解