CSU software 新手练习1 解题报告

1001 本题一般是新手的处女题。要熟悉ACM的输入输出规则。还是要注意一下题目里说的是Each line will contain two integers A and B. Process to end of file.也就是说有多组测试数据,要用循环去输入。cin是有返回值的,只要你不断的输入,循环就不会结束。还有,大家不用担心程序不会终止。其实你是可以手动终止程序的,当然,在OJ测试用的文件的末尾有一个EOF的标志,一旦读到了文件的末尾,程序就会终止。

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main(){
 5     int a,b;
 6     while(cin>>a>>b){
 7         cout<<a+b<<endl;
 8     }
 9     return 0;
10 }
View Code

1002 估计大家做这个题的时候WA了或者TLE了或者PE了。

首先我估计大家做这个题会碰到TLE的错误。TLE就是超时。这个题目求一个1+2+……+n的和 如果你用循环去写 你算算每组样例需要算多少次  显然是n是多少就需要算多少次了 这个题目的时间限制是1000ms 也就是1秒 在OJ上 1秒钟大概可以运算200000000次 如果我数据比较多 你就有超时的危险了。 这就是个简单的等差数列求和嘛。。你直接这样用等差数列求和的公式写就行了 你可以比较一下运行效率 一个是输入n我要算n次 另外是输入n我算1次就直接得到答案了。。ACM对算法的运行效率要求还是蛮高的。所以下手之前要先考虑一下效率啊。。

如果你第一次提交不是因为用循环去累加出现TLE的情况,而是确实用了一个等差数列求和的公式而WA掉了,那么,首先恭喜你,你还是挺聪明的。题目里说,答案保证不超过32位有符号整数的范围,也就是说,你输出一个int型的整数,应该是不会出错的。但是这里有一个小陷阱,(1+n)*n可能超出32bit有符号整数的范围。这时候你的(1+n)*n被系统默认为了一个32位有符号整数,因此它就不是原来该是的数字了,因此再拿它 /2 的话,答案就错了。所以,如果你将n定义为long int型或者unsigned int型,就不会出现问题了。

写法一,这样避免了在计算中数字的范围超出了int的范围的问题:

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main(){
 5     int n;
 6     while(cin>>n){
 7         if(n&1) cout<<(n+1)/2*n<<endl<<endl;
 8         else    cout<<n/2*(n+1)<<endl<<endl;
 9     }
10     return 0;
11 }
View Code

写法二,直接用个long long就OK了。(我试了一下,用long还不行)

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main(){
 5     long long n;
 6     while(cin>>n){
 7         cout<<(n+1)*n/2<<endl<<endl;
 8     }
 9     return 0;
10 }
View Code

1003 如果你是自己想到怎么解决这个问题并且自己把这个代码敲出来的话,那么我只能说,你太NB了,你真的很适合ACM。当然,如果你能想到方法,但是暂时还没有能力敲出来,那么可以参考一下下面这份我写的代码,因为毕竟大家刚学C++不久,编码量还没有达到那个程度。如果你暂时没有想到,这也没关系。其实方法很简单,我们上小学的时候就学习过这个方法:列竖式计算。列竖式计算怎么算就不用我说了吧。至于怎么写,首先,用字符串读入整数,然后按位保存每一个位置上的数字,然后一位一位的去加,注意进位的情况,就可以了。

 1 #include <stdio.h>
 2 #include <string.h>
 3 char a[1005],b[1005];
 4 int aa[1005],bb[1005];
 5 int main()
 6 {
 7     int ncase,alen,blen,maxlen,c,i,k = 1;
 8     scanf("%d",&ncase);
 9     c = ncase;
10     while(ncase--)
11     {
12         memset(aa,0,sizeof(aa));
13         memset(bb,0,sizeof(bb));
14         scanf("%s",a);
15         scanf("%s",b);
16         alen = strlen(a);
17         blen = strlen(b);
18         maxlen = alen > blen ? alen : blen;
19         for(i = alen - 1;i >= 0;i--)
20             aa[alen - 1 - i] = a[i] - '0';
21         for(i = blen - 1;i >= 0;i--)
22             bb[blen - 1 - i] = b[i] - '0';
23         for(i = 0;i < maxlen;i++)
24         {
25             aa[i] += bb[i];
26             if(aa[i] >= 10)
27             {
28                 aa[i] -= 10;
29                 aa[i + 1] += 1;
30                 if(i + 1 == maxlen)
31                     maxlen++;
32             }
33         }
34         printf("Case %d:
",k);
35         printf("%s + %s = ",a,b);
36         for(i = maxlen - 1;i >= 0;i--)
37             printf("%d",aa[i]);
38         if(k == c)
39             printf("
");
40         else
41             printf("

");
42         k++;
43     }
44     return 0;
45 }
View Code

下面的题目都是让大家熟悉ACM游戏规则中输入输出规范的。

1004和1001完全一样。。就不贴代码了。

1005 告诉你输入的测试数据组数的情况

 1 #include <iostream>
 2 using namespace std;
 3 int main(){
 4     int a,b,T;
 5     cin>>T;
 6     while(T--){
 7         cin>>a>>b;
 8         cout<<a+b<<endl;
 9     }
10     return 0;
11 }
View Code

1006 告诉你输入的终止条件的情况

 1 #include <iostream>
 2 using namespace std;
 3 int main(){
 4     int a,b;
 5     while(cin>>a>>b){
 6         if(!a && !b)    break;
 7         cout<<a+b<<endl;
 8     }
 9     return 0;
10 }
View Code

1007 相信你自己可以搞定了,综合了1005和1006两种情形

 1 #include <iostream>
 2 using namespace std;
 3 int main(){
 4     int T;
 5     while(cin>>T){
 6         if(!T)  break;
 7         int tmp,sum = 0;
 8         for(int i = 0;i < T;i++){
 9             cin>>tmp;
10             sum += tmp;
11         }
12         cout<<sum<<endl;
13     }
14     return 0;
15 }
View Code

1008 应该没什么问题,还是差不多的

 1 #include <iostream>
 2 using namespace std;
 3 int main(){
 4     int T;
 5     cin>>T;
 6     while(T--){
 7         int n,tmp,sum = 0;
 8         cin>>n;
 9         while(n--){
10             cin>>tmp;
11             sum += tmp;
12         }
13         cout<<sum<<endl;
14     }
15     return 0;
16 }
View Code

1009 又是多组测试数据

 1 #include <iostream>
 2 using namespace std;
 3 int main(){
 4     int T;
 5     while(cin>>T){
 6         int tmp,sum = 0;
 7         while(T--){
 8             cin>>tmp;
 9             sum += tmp;
10         }
11         cout<<sum<<endl;
12     }
13     return 0;
14 }
View Code

1010 注意要求,每组后面要加空行

1 #include <iostream>
2 using namespace std;
3 int main(){
4     int a,b;
5     while(cin>>a>>b){
6         cout<<a+b<<endl<<endl;
7     }
8     return 0;
9 }
View Code

1011 如果你能够自己解决这题,那么恭喜你!ACM的输入输出规则就基本没有问题了。注意,相邻两组间需要输出空行,那么最后一组和倒数第二组之间会有空行,最后一组之后就不应该输出空行了。

 1 #include <iostream>
 2 using namespace std;
 3 int main(){
 4     int T;
 5     cin>>T;
 6     while(T--){
 7         int n,tmp,sum = 0;
 8         cin>>n;
 9         while(n--){
10             cin>>tmp;
11             sum += tmp;
12         }
13         cout<<sum<<endl;
14         if(T)   cout<<endl;
15     }
16     return 0;
17 }
View Code

1012 简单吧。。求绝对值

 1 #include <iostream>
 2 #include <iomanip>
 3 using namespace std;
 4 int main(){
 5     double a;
 6     while(cin>>a){
 7         if(a < 0)   a = -a;
 8         cout<<fixed<<setprecision(2)<<a<<endl;
 9     }
10     return 0;
11 }
View Code

1013 水仙花数 题目很简单。其实100-999的水仙花数只有5个。。这里需要注意点的是数个格式。 题目说:如果有多个,则要求从小到大排列在一行内输出,之间用一个空格隔开。比如说要求输出370,371。估计有很多同学的输出是这样"370space371space","space370space371",space代指空格。ACM的游戏规则就是这么严格,如果你像我前面那样输出,肯定是不会得到Accepted的,会得到一个PE。注意,后面的空格要去掉,要保证只有数字之间输出空格。

 1 #include <iostream>
 2 using namespace std;
 3 int num[100],cnt;
 4 void init(){
 5     cnt = 0;
 6     for(int i = 100;i <= 999;i++){
 7         int a = i/100,b = (i/10)%10,c = i%10;
 8         if(a*a*a + b*b*b + c*c*c == i)
 9             num[cnt++] = i;
10     }
11 }
12 
13 int main(){
14     init();
15     int a,b;
16     while(cin>>a>>b){
17         bool flag = false;
18         for(int i = 0;i < cnt;i++){
19             if(a <= num[i] && b >= num[i]){
20                 if(!flag){
21                     flag = true;
22                     cout<<num[i];
23                 }else{
24                     cout<<" "<<num[i];
25                 }
26             }
27         }
28         if(!flag)   cout<<"no";
29         cout<<endl;
30     }
31     return 0;
32 }
View Code

1014 C++实验级别的难度。就是要注意一下字符串怎么读。字符串有很多种读法,这里用了一种上课老师讲过的cin.getline(a,b,c)的函数,三个参数a,b,c的意义分别是字符指针,字符个数N,结束符。还要注意,你在读样例组数的时候,会把' '也读进来,要记得先把它吃掉再去读字符串,不然你会发现,你第一组样例还没有输入,就给你输出一个0了,因为系统默认了你的第一个字符串就是' '。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 char str[10000];
 6 int main(){
 7     int T;
 8     cin>>T;
 9     getchar();
10     while(T--){
11         cin.getline(str,9999,'
');
12         int cnt = 0;
13         for(int i = 0;i < strlen(str);i++){
14             if(str[i] >= '0' && str[i] <= '9')
15                 cnt++;
16         }
17         cout<<cnt<<endl;
18     }
19     return 0;
20 }
View Code

1015 sort函数,一定要会用啊。比赛的时候很可能用到。

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 char a[3];
 5 int main(){
 6     while(cin>>a[0]>>a[1]>>a[2]){
 7         sort(a,a+3);
 8         cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<endl;
 9     }
10     return 0;
11 }
View Code

1016 套公式,会吧。

 1 #include <iostream>
 2 #include <iomanip>
 3 #include <cmath>
 4 using namespace std;
 5 
 6 int main(){
 7     double x1,x2,y1,y2;
 8     while(cin>>x1>>y1>>x2>>y2){
 9         cout<<fixed<<setprecision(2)<<sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))<<endl;
10     }
11     return 0;
12 }
View Code

1017 肯定没问题啊。

 1 #include <iostream>
 2 #include <iomanip>
 3 using namespace std;
 4 
 5 int main(){
 6     int m,n;
 7     cin>>m;
 8     while(m--){
 9         double sum = 0;
10         cin>>n;
11         for(int i = 1;i <= n;i++){
12             if(i&1) sum += 1.0/i;
13             else    sum -= 1.0/i;
14         }
15         cout<<fixed<<setprecision(2)<<sum<<endl;
16     }
17     return 0;
18 }
View Code
原文地址:https://www.cnblogs.com/zhexipinnong/p/3422466.html