codeforces A. Strange Addition 解题报告

题目链接:http://codeforces.com/problemset/problem/305/A

题目意思:给出一个序列,需要从中选择一些数,这些数需要满足:任意的两个数中每一位至少有一个数满足该位有0。例如,406, 10(可以看成010)是符合条件的; 406, 11 就不符合条件,因为个位上这两个数都不包含0。

      一开始想得太过复杂:把整型的数保存到字符数组中,再用strstr函数找出是否有0的存在,但是这样做根本不能解决问题,因为不能得出0的具体位置。并且不能判断出两个数中的不同位至少有一个有0这个问题;后来甚至想到用位运算,看了下tutorial,原来又把问题想复杂了。

       其实,解决的方法不难。首先看数据范围,最大是100,最小是0。这两个数肯定是要保存下来的,因为它和任何一个在区间(0, 100)中的数相加都符合每一位至少有一个数有0。接着考虑个位上的数,即(0,10),只需要保存一个,还有[10, 100)中被10整除的数,也是只需要保存一个。举个例子,比如8,30, 100, 0,两两组合都符合至少两个数中满足某一位是0的(不够位的,可以在前面添0,8可以看成008或者08)。至于[10, 100)中不能被10整除的数有一种情况也是需要只保存一个的,就是当序列中只有0或100或两个同时都有。

       特别要注意一个比较容易遗忘的细节,很阴险的说~~~当序列中只有一个数的时候,无论是什么,都需要输出。隐含是满足条件的!!!卑鄙!!!

      

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 using namespace std;
 5 
 6 const int maxn = 100 + 5;
 7 int ans[maxn];
 8 
 9 int main()
10 {
11     int i, k, tmp, tmp1, cnt, cnt1, flag, flag1, flag2, flag3;
12     while (scanf("%d", &k) != EOF)
13     {
14     //    freopen("in.txt", "r", stdin);
15         flag = flag1 = flag2 = flag3 = 0;
16         cnt1 = cnt= 0;
17         for (i = 0; i < k; i++)
18         {
19             scanf("%d", &tmp);
20             if ((tmp == 0 || tmp == 100) && cnt1 <= 2)  // 0 or 100,cnt1不用也可以,只是为了严谨,防止序列中有多个重复的0或100
21             {
22                 ans[cnt++] = tmp;
23                 cnt1++;
24                 flag = 1;
25             }
26             else if (tmp >= 10 && tmp < 100) // [10, 100)
27             {
28                 if (tmp % 10 == 0 && !flag1)  // 10的倍数
29                 {
30                     ans[cnt++] = tmp;
31                     flag1 = 1;
32                 }
33                 else if (!flag2)  // 不是10的倍数
34                 {
35                     tmp1 = tmp;   // 暂时保留,因为有可能不需要输出
36                     flag2 = 1;
37                 }  
38             }
39             else if (tmp > 0 && tmp < 10 && !flag3)  // (0, 10)
40             {
41                 ans[cnt++] = tmp;
42                 flag3 = 1;
43             }
44         }
45         if (flag && !flag1 && !flag3 && k != 1)
46         {
47             if (flag2)    // 这个条件十分关键
48                 ans[cnt++] = tmp1;
49         }
50         if (flag2 && !flag && !flag1 && !flag3)
51             printf("1
%d
", tmp);
52         else
53         {
54             printf("%d
", cnt);
55             for (i = 0; i < cnt; i++)
56                 printf("%d ", ans[i]);
57             printf("
");
58         }
59     }
60     return 0;
61 }
原文地址:https://www.cnblogs.com/windysai/p/3383161.html