解题报告.docx
《解题报告.docx》由会员分享,可在线阅读,更多相关《解题报告.docx(13页珍藏版)》请在冰豆网上搜索。
![解题报告.docx](https://file1.bdocx.com/fileroot1/2022-12/14/c47efca3-7722-4308-a263-9b8d52f63446/c47efca3-7722-4308-a263-9b8d52f634461.gif)
解题报告
2012级新生练习赛1(解题报告)
A.HelloACM!
如题,本题是一很基本输出啦,不过注意输出换行,和大小写,其实ctrl+c更直接,不必担心大小写错误…..
B.加减乘除
#include
intmain()
{
inta,b,i=0;
doublec;
while(scanf("%d%d",&a,&b)&&(a||b))//注意测试多组数据表示方法
{
i++;
c=(double)a/b;//对a/b强制转换类型才可以输出正确结果
printf("Case%d\n",i);
printf("%d\n",a+b);
printf("%d\n",a-b);
printf("%d\n",a*b);
printf("%.2lf\n",c);//注意保留两位小数
}
}
这题也是比较水吧,只要认真读题,注意输出格式应该不会出问题…
PS:
1.对多组数据的测试方法一定要学会,在ACM中肯定会用到,建议先做杭电的1090~~1096题,很经典的入门题,自我感觉是。
2.在进行运算过程中一定要注意整型和浮点型之间的运算,对于本题整型除整型还是整型,所以要强制转换数据类型。
C.两点间距离
#include
#include//下面用到sqrt数学函数,所以要加该头文件
intmain()
{
doublex1,y1,x2,y2;//数据直接定义为double会更方便下面的数据处理
while(scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2)!
=EOF)
{
doublel;
l=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
printf("%.2lf\n",l);//还是保留小数
}
return0;
}
感觉这题继续水了…..
PS:
1.需要注意的注释都写了
2.特别提醒再用到其它函数的时候,一定要注意头文件
D.浮点数的加减乘除
#include
intmain()
{
doublea,b;
while(scanf("%lf%lf",&a,&b)!
=EOF)
{
if((a+b)>-0.000000005&&a+b<0)
printf("0.00000000\n",a+b);
elseprintf("%.8lf\n",a+b);
if((a-b)>-0.000000005&&a-b<0)
printf("0.00000000\n",a-b);
elseprintf("%.8lf\n",a-b);
if((a*b)>(-0.000000005)&&a*b<0)
printf("0.00000000\n",a*b);
elseprintf("%.8lf\n",a*b);
if((a/b)>-0.000000005&&a/b<0)
printf("0.00000000\n",a/b);
elseprintf("%.8lf\n",a/b);
printf("\n");
}
}
对这题表示真的很无语很无语,几乎一天都在纠结这题,先说下我的错误吧,开始以为是取小数点后八位,最后一位不四舍五入,纯属对题理解错误,然后想进一切办法去取后八位,最后是失败了,直到题下出暗示,才明白过来自己理解错了。
知道正确题意后,又是一通错误啊,开始只是/进行了处理(当时实在太困了,脑袋全蒙了),处理时还对条件句里的判断条件给整错了,不过最后总算整对了…
PS:
1.一定要注意审题,把握好题意,这是做对一个题的先决条件,自从刷题以来,误解了很多次题意了,今后一定一定注意读题,敲完代码后一定也要多测试几组数据,特别是那种特殊边缘数据。
2.感觉本题主要是对结果的处理方法的一种考察吧,这个程序应该还可以继续优化一下….
E.逆转数列
#include
intmain()
{
inta[200];
inti,n;
while(scanf("%d",&n)!
=EOF)
{
for(i=0;iscanf("%d",&a[i]);
i=n-1;
for(i;i>=0;i--)
{
printf("%d",a[i]);
if(i>0)printf("");
}
printf("\n");
}
}
这题仔细看过书的话应该问题不大,主要思想就是开辟一足够大数组,输入数字的时候存入数组内,然后按下标逆序输出就ok了….
PS:
1.思路应该很简单,但是实际操作可能会出问题,尤其是要求没输出一个数就隔一空格,但最后一位数后无空格,记得刚开始做这种题的时候直接很笨的用%d(有个空格)来去输出,,最后提交才发现错了,对于这种输出空格的题应格外注意,因为空格看不到,很容易多输出或少输出,不过可以用printf("a");这种方法去检测自己的空格输出,哪里有a哪里就有空格输出。
感觉这种方法很好用,不仅可以测试空格的输出,还可以用于其它类型的测试,特别是下面的9*9歌中进行测试。
F.九九歌1
#include
intmain()
{
inti,j,n;
while(scanf("%d",&n)!
=EOF)
{
for(i=1;i<=n;i++)//外层循环要进行n次
{
for(j=1;j<=i;j++)//内层循环要到j=i,也就是到i*i;
{
printf("%3dx%3d=%3d",i,j,j*i);//运算符左右都有空格,还有输出控制的对齐,题中有详解
if(i!
=j)
printf("");//注意空格输出的要求
}
printf("\n");
}
printf("\n");//每输出一个乘法口诀表要换行
}
}
本题主要思路就是用两层for循环去控制每次的等式变化,如题中所说如果不仔细读题很容易出现PE,所以在这题一定要仔细检查空格和换行的输出
G.九九歌2
本题和上差不多,主要是多输出所占字符的控制,实在想不出用循环去控制,只好暴力的输出了
#include
intmain()
{
inti,j,n;
while(scanf("%d",&n)!
=EOF)
{
for(i=1;i<=n;i++)
{
for(j=1;j<=i;j++)
{
if(n*n<10)//和上题就这点区别,判断一下表中最大数,暴力的输出
printf("%2dx%2d=%2d",i,j,j*i);
elseif(n*n<100)
printf("%3dx%3d=%3d",i,j,j*i);
elseif(n*n<1000)
printf("%4dx%4d=%4d",i,j,j*i);
elseif(n*n<10000)
printf("%5dx%5d=%5d",i,j,j*i);
elseif(n*n<100000)
printf("%6dx%6d=%6d",i,j,j*i);
if(i!
=j)
printf("");
}
printf("\n");
}
printf("\n");
}
}
H.魔幻菱形
#include
intmain()
{
inti,j,k,n;
while(scanf("%d",&n)&&n)//注意当n=0时程序结束
{
for(i=0;i{
for(j=0;j<=n/2-1-i;j++)//对每行空格输出控制
printf("");
for(k=0;k<=2*i;k++)//对*号输出控制
printf("*");
printf("\n");
}
for(i=0;i{
for(j=0;j<=i;j++)
printf("");
for(k=0;kprintf("*");
printf("\n");
}
}
}
感觉这题算是这些题里逻辑性较大的一个吧,特别是对每行空格和*号的输出控制,上半部分还好些,自己就在下半部分的输出费了好大会时间,最后突然明白过来,下半部分输出时,以中间行最长的为基础,然后依次每行输出减2就ok了,就这种控制for(k=0;kPS1.上半部分一直输出到最长的那行
2.感觉应该可以用数组的办法输出,但还没尝试。
。
。
。
I.字符统计器
#include
#include
intmain()
{
intn,j=0;
chara[200];//对于未知数组尽量开辟到足够大
scanf("%d",&n);
getchar();//注意一定要对输入n后的回车处理掉,要不会出大错的,开始自己就忘了
while(n--)//又是一种处理多组数据的方法
{
inti=0;
j++;
intcnt1=0,cnt2=0,cnt3=0,cnt4=0,cnt5=0;
while((a[i]=getchar())!
='\n')//因为还要对空格读取,故不能用%s读入,这种写法表示遇到回车结束读入
{
if(a[i]<='Z'&&a[i]>='A')//对每个字符逐个检测
cnt1++;
elseif(a[i]<='z'&&a[i]>='a')
cnt2++;
elseif(a[i]=='')
cnt3++;
elseif(a[i]<='9'&&a[i]>='0')
cnt4++;
elsecnt5++;//因标点不好统计所以放在最后
}
if(j==1)//控制表头只输出一次
printf("%6s%6s%6s%6s%6s\n","UPPER","LOWER","PUNCT","BLANK","DIGIT");
printf("%6d%6d%6d%6d%6d\n",cnt1,cnt2,cnt5,cnt3,cnt4);//占用字符空间的控制方法
}
}
做这题时还是对题意没理解好,开始代码都对了,但因为误解题意,把表头多次输出,导致一直错误,难度吧感觉没什么,认真点都能过的
PS1.一定要认真读题,看清每一个字,理解透每一句话
K.斐波那契数列
#include
intmain()
{
unsignedlonglonga[300];//斐波那契数到后面会很大很大的,注意定义好数据类型
inti,n,m;
scanf("%d",&n);
while(n--)
{
scanf("%d",&m);
if(m==0)//注意还有第0项
printf("0\n");
else
{
a[0]=1;a[1]=1;//该数列第一,二项为1
for(i=2;i<=50;i++)
{
a[i]=a[i-1]+a[i-2];//第三项等于前两项之和
}
printf("%llu\n",a[m-1]);//输出第m项也就是下标减一
}
}
}
本题只要理解斐波那契数列递变规律,就应该能够解决了,需要注意的是就是该数列到最后会递增到非常大,定义好数据类型,貌似测试数据有bug,不对第零项输出也是对的………
PS:
1.这题也可以直接累加去算,不过感觉程序语句过多,思路和这个差不多
L.找零钱
#include
intmain()
{
intn;
inti;
while(scanf("%d",&n)!
=EOF)
{
intcnt1=0,cnt2=0,cnt3=0,cnt4=0,cnt5=0,cnt6=0;
intm,sum=0;
while(n--)
{
scanf("%d",&m);
cnt1=m/100;//100元所需要的张数
cnt2=m%100/50;//50元所需要的张数
cnt3=m%100%50/20;//20元所需要的张数
cnt4=m%100%50%20/10;//10元所需要的张数
cnt5=m%100%50%20%10/5;//5元所需要的张数
cnt6=m%100%50%20%10%5/1;//1元所需要的张数
sum=cnt1+cnt2+cnt3+cnt4+cnt5+cnt6;//最少需要的张数
printf("%d\n",sum);
}
}
}
本题思路也很好找,既然需要最少张数,那么只要尽最大可能找面值大的就行了,在这个过程中利用好取整和取余运算就会使程序简便很多,感觉和取一个数字每个位数上的数字过程差不多,还有就是要对数据的初始化
M.闰年问题
#include
intmain()
{
intyear;
while(scanf("%d",&year)!
=EOF)
{
if(year%400==0||(year%4==0&&year%100!
=0))//注意闰年的判定条件
printf("Yes\n");
else
printf("No\n");
}
}
感觉很水,只要知道闰年判定条件就可以了,不过需要注意的是输出结果的大小写问题,建议还是直接从题上ctrl+c
N.三角形
#include
intmain()
{
intn,a,b,c;
scanf("%d",&n);
while(n--)//测试n组数据的方法
{
scanf("%d%d%d",&a,&b,&c);
if(a+b>c&&a+c>b&&c+b>a)//三角形判定条件
printf("YES\n");
else
printf("NO\n");
}
}
很简单的一题,注意下多组数据的测试方法就行了
I.字符串操作
#include
#include//后面要用到字符串的函数,要加此头文件
intmain()
{
charstr1[300],str2[300];
while(scanf("%s%s",str1,str2)!
=EOF)//字符串读入用%S,可以不读入空格和回车
{
intm,n,i;
m=strlen(str1);//测试字符串长度函数
n=strlen(str2);
printf("%d%d\n",m,n);
if(strcmp(str1,str2)==0)//字符串比较函数
printf("SAME\n");
elseprintf("NOTSAME\n");
for(i=0;str1[i]!
='\0';i++)//转换大小写
if(str1[i]<='z'&&str1[i]>='a')
str1[i]=str1[i]-32;
printf("%s\n",str1);
for(i=0;str2[i]!
='\0';i++)
if(str2[i]<='Z'&&str2[i]>='A')
str2[i]=str2[i]+32;
printf("%s\n",str2);
printf("%s\n",strcat(str1,str2));//字符串粘贴函数
printf("\n");
}
}
这算是这些题里代码最长的了,对字符串的操作有很好的锻炼,多多看书练习字符串的各种操作方法,很容易就可以过了
PS:
1.注意字符串比较不是比较其长度大小
2.再对大小写转换时逐个检测,然后做出对应变化
D题文艺型代码,上面的太不好看了
#include
#include
doublesig(doublex)
{
returnfabs(x)<1e-8?
0:
x;
}
intmain()
{
doublea,b;
while(scanf("%lf%lf",&a,&b)!
=EOF)
{
printf("%.8lf\n",sig(a+b));
printf("%.8lf\n",sig(a-b));
printf("%.8lf\n",sig(a*b));
printf("%.8lf\n",sig(a/b));
}
}
PS:
对于很多同学都是第一次做比赛题,对比赛输入测试多组数据不是太了解,在这里简单说一些,测试多组数据,是因为实际的需要,在我们写出一个程序,不可能说只输入一次就结束了,就比如计算器,这是可一无限制的输入计算,在今后的比赛题中都是多组数据的测试,不过这个不用着急,其实就那么几种控制输入多组数据输入的方法;
A:
while(scanf("%lf%lf",&a,&b)!
=EOF)这种是比较常见的方法,就是一直输入a,b不停止,注意!
=EOF一定不要忘记,具体意思暂不做解释,可以先这么记着,等敲多了再去理解,感性去的可以XX一下~~~。
还有就是该语句后不需要加分号,只需要把你下面和a,b有关的句子用花括号括起来即可,详见上面的例子;
B:
while(scanf("%lf%lf",&a,&b)&&(a||b))这个语句和上一个意思差不多,只是当a,b都是0的输入时候结束,即不再执行输入a,b
C:
while(scanf("%d",&n)!
=EOF)这种写法意思是首先输入一个数n,则下面可以输入n{个数;这也是一种常见写法
for(i=0;iscanf("%d",&m);
}
D:
scanf("%d",&n);
while(n--)
{
A;
B;
C;
}
这个意思是首先输入一个数n,然后while语句里面的程序会执行n次,自我感觉这个用是比较多的,在while里面可以嵌套使用以上的几种语句;
基本上要介绍的就这几种了,大家可以去杭电
去做1089~~~1096这几题比较经典的A+B,是很好的锻炼多组数据测试的题
再次PS:
各位同学一定要多多上机敲敲,每一个写好的程序都做好注释,保存好,一遍自己以后查看,以上用法慢慢熟悉,很快就能掌握
再再次PS:
12级计算机2班是最棒的,各位加油吧!
!
!
我们的未来是美好滴!
!
!
加油,相信自己永远都是最棒的