寒假作业之二(1)

github上的代码请点击1001. A+B Format20

先看看题目

看见题目,根据我被坑的经验,首先的反应就是:

  • **1.测试组数,题目意思应该是多组,那么就跑不了while(scanf()!=EOF)的类型 **
  • 2.范围,数量级是7次方,不大,int类型是21亿,所以,用int足够(虽然我经常是打开来dev,准备设置变量的时候,才会回头看范围)
    然后,我发现,这题和Fzu上一题基本上一样详情见FZU1405

做这题,我的第一反应就是,a+b的结果用字符串数组存起来,然后每经过3个字符,加一个‘,’,这样子就很简单了,所以要用到stdlib.h中的itoa函数,其中进制转换选择为十进制。

首先,测试一下看看函数用法有没有用错

第一次尝试结果

看来没有函数没有用错,然后接下来就是做题了

这题要注意的是,答案可能有正有负,这个很简单,只要判断一下正负,如果是负数,就输出‘-’,然后变成正数就可以按正的方法做了,定义变量k,统计当前字符个数(不包括负号)接下来只要每3个字符然后输出一个‘,’就完成了

然后代码为

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
    int a,b,c;
    char s[10];
    while(scanf("%d %d",&a,&b)!=EOF)
    {
	    c=a+b;
	    itoa(c,s,10);
	    int i=0,k=0;
	    if(s[0]=='-')
    	{
    		printf("-");
    		i=1;
    	 } 
    	while(s[i]!='\0')
    	{
    		printf("%c",s[i++]);
    		k++;
	    	if(k%3==0&&k!=0) printf(",");
	    }
	    printf("%s\n",s);
    }
 } 

由于题目给的数据测试太弱,只好自己测试


测试之后,发现错误很多,不仅忘记把第一次调试结果删除,而且忘记处理末尾逗号

然后继续改代码,判断如果下一个字符是‘\0’,就不加‘,’,把第一次调试的结果给注释了,加上换行

while(scanf("%d %d",&a,&b)!=EOF)
{
	c=a+b;
	itoa(c,s,10);
	int i=0,k=0;
	if(s[0]=='-')
	{
		printf("-");
		i=1;
	 } 
	while(s[i]!='\0')
	{
		printf("%c",s[i++]);
		k++;
		if(k%3==0&&k!=0&&s[i]!='\0') printf(",");
	}
	printf("\n");
//	printf("%s\n",s);
}

测试结果如下


然后发现- -,我忘记‘,’是从后往前加的了。。

所以,继续改代码,这个时候,就要用到统计字符串中字符个数的函数,
如果有5个字符,那么定义k一开始为1,所以第三个字符前有‘,’,如果有4个字符,那么定义k=2,第二个字符前有‘,’
这就要用到k=3-strlen(s)%3,而且不统计负号进去,

修改后代码如下

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
	int a,b,c;
	char s[10];
    while(scanf("%d %d",&a,&b)!=EOF)
    {
	    c=a+b;
    	itoa(c,s,10); 
	    int i=0,k=0;
	    if(s[0]=='-')
	    {
	    	printf("-");
		    i=1;
	     } 
	     int n=strlen(s);
	     n-=i;//去负号 
	     k=3-n%3; 
	    while(s[i]!='\0')
	    {
	    	printf("%c",s[i++]);
	    	k++;
		    if(k%3==0&&k!=0&&s[i]!='\0') printf(",");
	    }
	    printf("\n");
//		    printf("%s\n",s);
    }
    return 0;
 } 

测试


出错了。。。查了一下原因

咦,居然itoa函数在PAT上不能用,但是我把代码a+b改成a-b,提交到fzu上。明明可以的...然后我百度了一下,结果是,itoa不是标准的C函数库什么什么...

这时....我想起了与printf相对应的据说更实用的sprintf打印进数组的函数,然后我查了一下他的用法,

把itoa注释,改成sprintf函数

 sprintf(s,"%d",c);
 //	itoa(c,s,10); 

成功了。。
因为之前询问了一下大神关于itoa,他们说并没有用过,然后说直接写就好了,然后我顺便想了一下,发现其实不用字符串,也是挺简单的,先变为正的,然后分类讨论数的范围小于1000.1000~1000000,与大于10000000就好了(表示眼瞎一次,第一次范围看错为5个0,然后部分错误一次)然后记得用%.3d这个输出方式来补0,以中间一中情况为例,取1000为余数,保存后3位数字,然后再/1000,保存前面的位数,然后输出,后3位记得补0,就没什么问题了,

具体代码如下:

#include<stdio.h>
int main()
{
    int a,b,c,d,e;
    while(scanf("%d %d",&a,&b)!=EOF)
    {
	    c=a+b;
	    if(c<0)
	    {
	    	printf("-");
		    c*=-1;
	    }
	    if(c<1000) printf("%d",c);
	    else if(c<1000000)
	    {
	    	d=c%1000;
	    	c/=1000;
		    printf("%d,%.3d\n",c,d);
	    }
	    else
	    {
	    	d=c%1000;
	    	e=c%1000000;
	    	e/=1000;
	    	c/=1000000;
	    	printf("%d,%.3d,%.3d\n",c,e,d);
	    }
    }
 }

测试结果:


总结

  • 1.这题难度不大,数据范围不会过大,但测试数据比较弱,在提交前请至少要测试3位数以内,5位数以内,7位数以内的正数,与至少一组负数,才提交
  • 2.数据范围不要看错,第二种方法因为范围是7次方看出6次方导致部分错误一次....
posted @ 2016-01-28 22:26  洛丶航  阅读(186)  评论(2编辑  收藏  举报