C语言第五六次作业.ppt
C语言作业解析语言作业解析第四弹。原来真正变态的是这两作业哇原本是做完第五次作业等大家数分期中考完以后给大家,结果直接出了第六次。就顺便做了。买一送一还包邮哦亲虽然这两次作业比较难。理解起来困难无比。不过考试的时候不会有这么变态的题目啦放心当前编程题:当前编程题:11级第五次作业级第五次作业-凸多边形面积凸多边形面积1.【问题描述】给出平面上一组顶点的坐标,计算出它们所围成的凸多【问题描述】给出平面上一组顶点的坐标,计算出它们所围成的凸多边形的面积。边形的面积。【输入形式】从标准输入读取顶点坐标。格式为:第一行是点的个数【输入形式】从标准输入读取顶点坐标。格式为:第一行是点的个数N(3N15),后面紧接着),后面紧接着N行,每行两个数字行,每行两个数字(由空格隔开),分(由空格隔开),分别表示该点的别表示该点的X、Y坐标(坐标(0X,Y32767)。所有点的坐标互不相同,)。所有点的坐标互不相同,且按顺时针次序给出。且按顺时针次序给出。输入数据确保该多边形是一个凸多边形。输入数据确保该多边形是一个凸多边形。【输出形式】向标准输出打印一个浮点数,是该多边形的面积。该浮【输出形式】向标准输出打印一个浮点数,是该多边形的面积。该浮点数保留两位小数。点数保留两位小数。【输入样例】【输入样例】433301012【输出样例】【输出样例】5.00【样例说明】输入数据表示了如图所示的四边形。其面积为【样例说明】输入数据表示了如图所示的四边形。其面积为5.00。提示:求三角形面积可用海伦公式,求平方根可用提示:求三角形面积可用海伦公式,求平方根可用头文件中头文件中定义的定义的sqrt函数。函数。【评分标准】结果完全正确得【评分标准】结果完全正确得20分,每个测试点分,每个测试点4分。提交程序名为:分。提交程序名为:points.c。本题解析:这个题是把凸n边形面积分成n-2个三角形面积和来做的。用海伦公式S=sqrt(p*(p-a)*(p-b)*(p-c)P=(a+b+c)/2a,b,c为三边长例如n边形点为a1a2an那S=(Sa1akak+1)(2KN-1)边长则为两点间距离。#include#includeintmain()intn;floatx15,y15;inti;floatdx,dy;floattot=0;floata,b,c,p;scanf(%d,&n);for(i=0;in;i+)scanf(%f%f,&xi,&yi);for(i=1;in-1;i+)dx=x0-xi;dy=y0-yi;a=sqrt(dx*dx+dy*dy);/*两点间距离公式*/dx=xi-xi+1;dy=yi-yi+1;b=sqrt(dx*dx+dy*dy);dx=xi+1-x0;dy=yi+1-y0;c=sqrt(dx*dx+dy*dy);p=(a+b+c)/2;tot+=sqrt(p*(p-a)*(p-b)*(p-c);/*海伦公式*/printf(%.2f,tot);return0;当前编程题:当前编程题:11级第五次作业级第五次作业-整数的整数的N进制字符串表示进制字符串表示【问题描述】编写函数【问题描述】编写函数itob(n,s,b),用于把整数用于把整数n转换成以转换成以b为基的字符串为基的字符串并存储到并存储到s中中.编写程序编写程序,使用函数使用函数itob(n,s,b)将输入的整数将输入的整数n,转转换成字符串换成字符串s,将将s输出输出.转换后的字符串从最高的非零位开始输出。如转换后的字符串从最高的非零位开始输出。如果果n为负数,则输出的字符串的第一个字符为为负数,则输出的字符串的第一个字符为-。b为大于为大于1小于小于37的任意自然数值。当的任意自然数值。当b=2时,输出字符只可能是时,输出字符只可能是0和和1;当;当b=16时,输出字符串中可能含有字符为时,输出字符串中可能含有字符为0-9,a-f(字母以小写输出字母以小写输出)。b还可以是其它数值。比如输入还可以是其它数值。比如输入n=33,b=17,则,则输出输出33的的17进制值为进制值为1g。【输入形式】控制台输入整数【输入形式】控制台输入整数n和和b,其中,其中n可以为负数。可以为负数。n和和b以空格以空格分隔分隔.【输出形式】控制台输出转化后的字符串【输出形式】控制台输出转化后的字符串s.【样例输入】【样例输入】52【样例输出】【样例输出】101【样例说明】【样例说明】5的二进制就是的二进制就是101【评分标准】结果完全正确得【评分标准】结果完全正确得20分,每个测试点分,每个测试点4分。提交程序名为:分。提交程序名为:itob.c本题解析:十进制转换为其他进制的方法是不断除目标进制的数取余数,然后倒序输出。例如5变为二进制就是5%2=1;5/2=2;2%2=0;2/2=1;1%2=1;得到101倒序得到101即为正解。十进制以上则是若目标大于10就变为相应的字母即可。如果目标数为负数,则先忽略负号求解最后加上一个负号就可以了#include#includevoiditob(intn,chars,intb)intflag=1;intsum=0;inti,j;charch;if(n0)/*不断除b取余*/ssum+=n%b;n=n/b;for(i=0,j=sum-1;ij;i+,j-)/*将数字倒序存放*/ch=si;si=sj;sj=ch;for(i=0;isum;i+)if(si0;i-)si=si-1;s0=-;intmain()intn,b;chars100;scanf(%d%d,&n,&b);itob(n,s,b);printf(%s,s);return0;当前编程题:当前编程题:11级第五次作业级第五次作业-求两组整数的异或集求两组整数的异或集3.【问题描述】从标准输入中输入两组整数【问题描述】从标准输入中输入两组整数(每行不超过每行不超过20个整数,每组整数中元素个整数,每组整数中元素不重复不重复),合并两组整数,去掉在两组整数中都出现的整数,并按从大到小顺序排序合并两组整数,去掉在两组整数中都出现的整数,并按从大到小顺序排序输出(即两组整数集输出(即两组整数集“异或异或”)。)。【输入形式】首先输入第一组整数,以一个空格分隔各个整数;然后在新的一行上【输入形式】首先输入第一组整数,以一个空格分隔各个整数;然后在新的一行上输入第二组整数,以一个空格分隔,行末有回车换行。输入第二组整数,以一个空格分隔,行末有回车换行。【输出形式】按从大到小顺序排序输出合并后的整数集(去掉在两组整数中都出现【输出形式】按从大到小顺序排序输出合并后的整数集(去掉在两组整数中都出现的整数,以一个空格分隔各个整数)。的整数,以一个空格分隔各个整数)。【样例输入】【样例输入】51432879-65287101【样例输出】【样例输出】87321098742-6【样例说明】第一组整数为【样例说明】第一组整数为51432879-6,第二组整数分别为,第二组整数分别为5287101。将第一组和第二组整数合并(去掉在两组整数中都出现的整数。将第一组和第二组整数合并(去掉在两组整数中都出现的整数5和和1),),并从大到小顺序排序后结果为并从大到小顺序排序后结果为87321098742-6。【评分标准】该题要求输出两组整数的异或集,共有【评分标准】该题要求输出两组整数的异或集,共有5个测试点,提交程序文件名个测试点,提交程序文件名为为xor.c。本题解析:求异或,同时降序输出。那么将问题简化后可以发现如果将两个数组中的数都读进同一个数组然后降序排序若是数组中存在相同元素则不输出,若只出现一次则输出。那么结果与题目要求就相同了。#includeintmain()inta100;inti,j,k;intsum=0;charch;inttot=0;scanf(%d,&asum+);while(1)ch=getchar();if(ch=n)tot+=1;if(tot=2)break;scanf(%d,&asum+);/*这里是进行读入,由于一共有两行那么每读完一个数就读入一个字符判断这个字符是不是换行符,当出现两个换行符的时候读入结束*/for(i=0;isum;i+)for(j=i+1;jsum;j+)if(aiaj)k=ai;ai=aj;aj=k;/*降序排序*/asum=5257;/*保证asum不与前面的数相同*/intflag=0;/*flag表示已经输出了多少数,若为0则不需要先输出空格,否则输出空格与前面输出的数字隔开*/for(i=0;isum;i+)if(i=0)if(ai!=ai+1)if(flag)printf();printf(%d,ai);flag+;if(i!=0)if(ai!=ai+1)&(ai!=ai-1)if(flag)printf();printf(%d,ai);flag+;当前编程题:11级第五次作业-字符串中字符排序字符串中字符排序4.【问题描述】编写一个程序,从键盘接收一个字符串,然后按照字符顺序从小到大进行排序,并删除重复的字符。【输入形式】用户在第一行输入一个字符串。【输出形式】程序按照字符(ASCII)顺序从小到大排序字符串,并删除重复的字符进行输出。【样例输入】badacgegfacb【样例输出】abcdefg【样例说明】用户输入字符串badacgegfacb,程序对其进行按从小到大(ASCII)顺序排序,并删除重复的字符,最后输出为abcdefg【评分标准】结果完全正确得20分,每个测试点4分。提交源程序名为stringsort.c本题解析:这个题做法比较多。一种简单的做法是:由于一共只有255个ascii码的值。那么开一个300的数组aai表示ascii码为i的字符出现的次数,输出时从0到255(或255以上,例如300)循环,若ai不为0则输出对应的字符。#include#includeintmain()inta300;inti,j;chark;chars200;memset(a,0,sizeof(a);scanf(%s,s);for(i=0;istrlen(s);i+)asi+;for(j=0;j260;j+)if(aj)k=j;printf(%c,k);当前编程题:当前编程题:11级第五次作业级第五次作业-最长升序子串最长升序子串5.【问题描述】输入一行字符串,该字符串只由小写英文字母【问题描述】输入一行字符串,该字符串只由小写英文字母a-z组成,且组成,且其中的字符可以重复,最长不超过其中的字符可以重复,最长不超过10000个字符。个字符。从该字符串中按顺序挑选出若干字符(不一定相邻)组成一个新串,称为从该字符串中按顺序挑选出若干字符(不一定相邻)组成一个新串,称为“子串子串”。如果子串中每两个相邻的字符或者相等,或者后一个比前一个大,。如果子串中每两个相邻的字符或者相等,或者后一个比前一个大,则称为则称为“升序子串升序子串”。编程求出输入字符串的最长升序子串的长度。编程求出输入字符串的最长升序子串的长度。例如,由输入字符串例如,由输入字符串abdbch可以构成的升序子串有:可以构成的升序子串有:abd、abch、bbch、abbch等。其中最长的升序子串是等。其中最长的升序子串是abbch,其长度为,其长度为5。【输入形式】从标准输入读取一行字符串,该串不含空格,以回车符结束。【输入形式】从标准输入读取一行字符串,该串不含空格,以回车符结束。【输出形式】向标准输出打印一个正整数,是字符串中最长的升序子串的长【输出形式】向标准输出打印一个正整数,是字符串中最长的升序子串的长度,在行末要输出一个回车符。度,在行末要输出一个回车符。【输入样例】【输入样例】abdbch【输出样例】【输出样例】5【样例说明】【样例说明】abdbch中最长子串是中最长子串是abbch,长度是,长度是5。【评分标准】结果完全正确得【评分标准】结果完全正确得20分,每个测试点分,每个测试点4分。上传分。上传c语言源程序为语言源程序为up.c。本题解析:这道题是从出现作业为止最难得题目。涉及到一些动态规划的思想。(我只想到这一种做法,欢迎大家有简单做法的来分享)用fij表示到字符串s中的第i个字符为止最高位为j(用1-26分别代替a-z)的最长字串的字符数。动态转移方程为:Fij=Fi-1j(sij)Fij=max(fi-1k)+1(1kj)(si=j)这个题目不是很好讲清楚,如果想透彻的理解的话可以来找我(中408JRC)不过。不保证一定能讲清楚。#include#includeintmain()chars10001;intf1000127;inti,j,k,l;scanf(%s,s);l=strlen(s);memset(f,0,sizeof(f);/*f数组初始化*/f0s0-a+1=1;/*f0s0对应的值应该是1,因为以s0为终结的最长字串长度为1*/for(i=1;il;i+)for(j=1;j=26;j+)if(j=si-a+1)for(k=1;k=j;k+)if(fijfi-1k+1)fij=fi-1k+1;elsefij=fi-1j;intmax=0;for(i=1;imax)max=fl-1i;printf(%d,max);当前编程题:当前编程题:11级第五次作业级第五次作业-字符串替换(新)字符串替换(新)6.【问题描述】编写程序将一个指定文件中某一字符串替换为另一个字【问题描述】编写程序将一个指定文件中某一字符串替换为另一个字符串。要求:(符串。要求:(1)被替换字符串若有多个,均要被替换;()被替换字符串若有多个,均要被替换;(2)指定的)指定的被替换字符串,大小写无关。被替换字符串,大小写无关。【输入形式】给定文件名为【输入形式】给定文件名为filein.txt。从控制台输入两行字符串(不含。从控制台输入两行字符串(不含空格,行末尾都有回车换行符),分别表示被替换的字符串和替换字符空格,行末尾都有回车换行符),分别表示被替换的字符串和替换字符串。串。【输出形式】将替换后的结果输出到文件【输出形式】将替换后的结果输出到文件fileout.txt中。中。【评分标准】该题要求得到替换后的文件内容,共有【评分标准】该题要求得到替换后的文件内容,共有5个测试点。上传个测试点。上传C语言文件名为语言文件名为replace.c。本题解析:这个题就是首先用一个字符串将filein.txt中的东西全部读入进来,然后进行一个判断与替换。对每一小段字符串都判断是不是与需要被替换的东西相等即可。#include#includechara200,b200,c2000;intjudge(inti,intl)/*判断从第i位开始的l位是否与待替换字符串一样*/intj;for(j=0;jl;j+)if(ci+j!=aj)&(ci+j!=aj+a-A)&(ci+j!=aj+A-a)/*注意大小写*/return0;return1;intmain()intl,i,len=0;charch;scanf(%s,a);scanf(%s,b);l=strlen(a);freopen(filein.txt,r,stdin);freopen(fileout.txt,w,stdout);memset(c,0,sizeof(c);while(ch!=EOF)ch=getchar();clen+=ch;for(i=0;i=len-1)/*如果剩余字符数不到待替换字符串的长度的时候直接输出就可以了*/printf(%c,ci);elseif(judge(i,l)/*如果一致的话就替换*/printf(%s,b);i+=l-1;else/*否则输出当前位*/printf(%c,ci);exit(0);return0;11级第六次作业-合并字符串合并字符串1.【问题描述】编写一个函数char*str_bin(char*str1,char*str2),str1、str2是两个有序字符串(其中字符按ASCII码从小到大排序),将str2合并到字符串str1中,要求合并后的字符串仍是有序的,允许字符重复。在main函数中测试该函数:从键盘输入两个有序字符串,然后调用该函数,最后输出合并后的结果。【输入形式】分行从键盘输入两个有序字符串(不超过100个字符)【输出形式】输出合并后的有序字符串【输入样例】acegbdfh【输出样例】abcdefgh【样例说明】输入两个有序字符串aceg和bdfh,输出合并后的有序字符串abcdefgh【评分标准】结果完全正确得20分,每个测试点4分,提交程序文件名为combine.c。本题解析:这道题主要用到了双队列维护。就是说将两个字符串看为两个队列,然后从排头开始出列,哪一列的排头比较小就出列同时出现一个新的排头。也就是原来的排头后面的那个字符#include#includecharstr3200;voidstr_bin(charstr1,charstr2)intl1,l2;l1=strlen(str1);l2=strlen(str2);/*分别为队列长度*/inti=0,j=0,k=0;while(il1|jl2)if(str1i=0)str3k+=str2j+;/*如果第一列的人都出列了则出列第二列的*/elseif(str2j=0)str3k+=str1i+;elseif(str1istr2j)str3k+=str1i+;/*否则的话比较大小,谁小谁出*/elsestr3k+=str2j+;str3k=0;intmain()charstr1100,str2100;scanf(%s%s,str1,str2);str_bin(str1,str2);printf(%s,str3);11级第六次作业-删除子串删除子串2.【问题描述】编写一个程序,当在一个字符串中出现子串时就删除它。【输入形式】用户在第一行输入一个字符串,用户在第二行输入一个子串。【输出形式】程序在下一行输出删除其中所有子串后的字符串。如果字符串不包含子串则输出原字符串本身。【样例输入】Iamaboy!a【样例输出】Imboy!【样例说明】用户首先输入字符串Iamaboy!,然后输出子串a,程序会寻找字符串中的子串删除它,最后将删除后的结果输出:I#m#boy!#表示空格。【评分标准】结果完全正确得20分,每个测试点4分。提交程序名为:delsubstring.c。本题解析:这道题跟第五次作业的最后一题基本一样。只不过被替换的字符串变成了空的而已。解析见第五次作业第六题。#include#includechara200,b200;intjudge(inti,intl)intj;for(j=0;jl;j+)if(ai+j!=bj)return0;return1;intmain()intl;gets(a);gets(b);l=strlen(b);inti;for(i=0;istrlen(a);i+)if(judge(i,l)i+=l-1;elseprintf(%c,ai);return0;/*不过感觉程序上简单多了。*/11级第六次作业-超长正整数的减法超长正整数的减法3.本题解析:高精度减法。因为是两个正整数。所以先要去掉题目描述的最高位处的多余的0其次是比较两个数字的大小。如果被减数小于减数,则是输出一个符号然后将两个数对调。注意,由于此处是高精度数,读入时需要直接使用字符串读入,采用竖式相减得方法还要考虑退位的问题。同时要从个位数开始相减。#include#includeintc101;intjudge(chara,charb)/*判断a与b的大小关系*/inti;if(strlen(a)strlen(b)return1;for(i=0;istrlen(a);i+)/*一样多的话逐位比较大小,第一位不同的谁大则谁比较大*/if(aibi)return0;return1;voidminus(chara,charb)/*减法操作*/inti,j;chark;for(i=0,j=strlen(a)-1;ij;i+,j-)/*首先将字符串倒过来,方便从个位开始相减*/k=ai;ai=aj;aj=k;for(i=0,j=strlen(b)-1;ij;i+,j-)k=bi;bi=bj;bj=k;for(i=0;i=strlen(b)ci=ai-0;elseci=ai-bi;for(i=0;istrlen(a)-1;i+)/*退位操作*/*下页还有*/if(ci0)ci+=10;ci+1-=1;intmain()inti,j,k,s=0,l;chara100,b100;memset(c,0,sizeof(c);gets(a);gets(b);while(as=0)s+;/*去掉多余的0*/l=strlen(a)-s;for(i=0;i=l;i+)ai=ai+s;s=0;while(bs=0)s+;l=strlen(b)-s;for(j=0;j=l;j+)bj=bj+s;if(judge(a,b)minus(a,b);elseprintf(“-”);minus(b,a);/*如果a=0;j-)printf(“%d”,cj);/*输出结果*/当前编程题:11级第六次作业-旋转魔方阵旋转魔方阵(文件文件)4.【问题描述】输入一个自然数(2N9),要求输出如下的魔方阵,即边长为N*N,元素取值为1至N*N,1在左上角,呈顺时针方向依次放置各元素。N=3时:123894765【输入形式】从标准输入读取一个整数N。【输出形式】将结果输出到文件文件file.out。输出符合要求的方阵,每个数字占5个字符宽度,向右对齐,在每一行末均输出一个回车符。【输入样例】4【输出样例】输出文件file.out内容为:12341213145111615610987本题解析:模拟做法。因为是n*n的一个矩阵,所以我只需要不停地转圈赋值即可。这个看程序会比较清楚。#includeintmain()freopen(file.out,w,stdout);intn,i,j,k=1,x=1,y=1,s=1,t,tot;intp1010;scanf(%d,&n);tot=n*n;t=n;while(1)while(x=t)px+y=k+;/*goright*/x-;k-;if(k=tot)break;/*如果已经填充了n*n个了就退出循环*/while(y=s)px-y=k+;/*goleft*/x+;k-;while(ys)pxy-=k+;/*goup*/y+;k-;s+;t-;/*矩阵缩小一层*/if(k=tot)break;for(i=1;i=n;i+)for(j=1;j=n;j+)printf(%5d,pji);printf(n);exit(0);11级第六次作业-全排列数的生成全排列数的生成5.【问题描述】输入整数N(1=N=10),生成从1N所有整数的全排列。【输入形式】输入整数N。【输出形式】输出有N!行,每行都是从1N所有整数的一个全排列,各整数之间以空格分隔。各行上的全排列不重复。输出各行遵循“小数优先”原则,在各全排列中,较小的数尽量靠前输出。如果将每行上的输出看成一个数字,则所有输出构成升序数列。本题解析:这道题如果做法太过暴力的话可能会超时。于是我们用一种半数学的方法。也就是说n的全排列按顺序排好的话,前(n-1)!个的第一位都是1,第二位就跟(n-2)!有关那么我们就可以通过第x个直接判断从第一位到第n位应该是第几个数,如果遇到这个数已经被使用了的情况的话就将这个数+1.以此类推#includeintmain()inti,j,k,n,s,f,p;intjc11=1,1,2,6,24,120,720,5040,40320,362880,3628800;/*0-10的阶乘*/intjudge11;/*用来判断1-10是否已经输出过*/scanf(%d,&n);for(i=1;i=jcn;i+)/*n的全排列共n!个*/s=i;memset(judge,0,sizeof(judge);for(j=0;jn;j+)/*n的全排列共n位*/if(j!=0)printf();p=(s-1)/jcn-1-j+1;/*p表示这次输出的数应该是第几个没出现过的数*/for(k=1;k=p;k+)if(judgek)p+;/*如果比p小的数中有的数出现过那么p就只能+1*/printf(%d,p);judgep=1;s=(s-1)%jcn-1-j+1;/*去掉(n-1)!项*/*其实这个题的做法类似Taylor展开式,还是比较显然的*/printf(n);return0;11级第六次作业-单词排序(命令行参数)单词排序(命令行参数)6.【问题描述】编写一个程序,从一个文件中读入单词(即:以空格分隔的字符串),并对单词进行排序,删除重复出现的单词,然后将结果输出到另一个文件中。【输入形式】源文件名和目标文件名在执行时作为程序命令行参数输入,例如若程序名为sort,源文件名和目标文件名分别为sort.in和sort.out,则命令行为:sortsort.insort.out。程序将从当前目录下sort.in文件中读入单词。【输出形式】对单词进行排序,删除重复出现的单词,然后将结果输出到文件sort.out中。【输入样例】假如sort.in文件内容如下:rrrsssaaabbbcccddfaaadd【输出样例】sort.out文件内容为:aaabbbcccddddfrrrsss【样例说明】读入文件sort.in,做适当的排序,并删除重复出现的单词,输出到文件sort.out【评分标准】对单词进行排序,删除重复出现的单词,符合此要求得20分,每个测试点4分,提交程序名为sortwords.c。本题解析:本题题目与前面很多题目都类似,题目本身并不难,主要是一个叫做“命令行参数”的东西。命令行参数就是在main函数中定义参数intmain(intargc,char*argv)argc表示参数的个数,argv即存储了各个参数按题目要求的testtest.intest.outargv0=“test”argv1=test.inargv2=“test.out”#include#includeintmin(inta,intb)if(ab)returna;elsereturnb;intjudge(chara,charb)/*判断a与b的大小关系*/intl1,l2,l,i;l1=strlen(a);l2=strlen(b);l=min(l1,l2);for(i=0;i=l;i+)if(aibi)return1;return2;/*ab返回1,a=b返回2*/intmain(intargc,char*argv)freopen(argv1,r,stdin);freopen(argv2,w,stdout);chars100100;charch,t100;inti=0,j,k=0;scanf(%s,sk+);while(ch=getchar()=)scanf(%s,sk+);for(i=0;ik-1;i+)for(j=i;j=sj*/strcpy(t,si);/*字符串不能直接赋值,只能用这个函数,相当于t=si*/strcpy(si,sj);strcpy(sj,t);printf(%s,s0);for(i=1;ik;i+)if(judge(si-1,si)!=2)/*如果这个与之前的单词不相同*/printf(%s,si);exit(0);随着题目越来越难,maybe很多以前觉得c语言还能忍的同学已经不能忍了。不过。大家都是6系的同学。我们都讨厌c语言c语言就木有活路了。想要本次ppt电子版的同学加我qq吧。JRC:631157428加油