Codeforces Round #696 (Div. 2)

Posted on 2021-01-21 13:30  jinxes6  阅读(117)  评论(0)    收藏  举报

放假之后的第一天,打着玩,状态有点差,写了两个题,第三个WA了一发就摸鱼去了

 

A.

题意:给两个长度均为n(1e5)的01串ab,ab的和为c,c的长度也是n。当ab的某一位均为1,c的这一位可以为2(总之就是不进位)。当c的连续的某几位相等时,就把连续的合并成一个,这样得到d。这个题目中,n和b已经给定,让你找到一个a使最后得到的d最大

 

分析:这个题要求d最大,那么最好的情况就是c的相邻的两位值都不相同,并且高位尽可能大。这样贪心的策略就很明显了,a从高到低,能取1的时候就取1,当取1的时候得到的c与高一位的相同时,a就只能取0。从高到低跑一遍就好了

 

代码:

 1 char str[100010];
 2 
 3 int main()
 4 {
 5     int T = 1;
 6     T = read();
 7     while (T --)
 8     {
 9         int n;
10         n = read();
11         scanf ("%s", str);
12         int pre = 0;
13         for (int i = 0; i < n; i ++)
14         {
15             int now = str[i] - '0';
16             if(pre == now + 1)
17             {
18                 printf ("0");
19                 pre = now;
20             }    
21             else
22             {
23                 printf ("1");
24                 pre = now + 1;
25             }
26         }
27         printf ("\n");
28     }
29     return 0;
30 }
A

 

 

B.

题意:给定一个数d(1e4),要求找到一个最小的数,满足它的因子数>=4并且它们之间的相差>=d

 

分析:这个题容易造成误解(就是这个原因WA了一发,后面过了之后才发的公告),开始以为直接是1,1+d,1+2d,(1+d)(1+2d),后面发现如果1+d或者1+2d不为质数的时候,这个数会有其它的因子,导致不符合要求。所以应找到一个质数a满足a>=1+d,然后再找到质数b满足b>=a+d,最后的答案就是a*b

 

代码:

 1 bool prime(int x)
 2 {
 3     for (int i = 2; i * i <= x; i ++)
 4         if (x % i == 0) return false;
 5     return true;
 6 }
 7 
 8 int main()
 9 {
10     int T = 1;
11     T = read();
12     while (T --)
13     {
14         int a = read();
15         int ans1, ans2;
16         ans1 = 1 + a;
17         while (!prime(ans1)) ans1 ++;
18         ans2 = ans1 + a;
19         while (!prime(ans2)) ans2 ++;
20         printf ("%d\n", ans1 * ans2); 
21     }
22     return 0;
23 }
B

 

刚回家,去做一个核酸,剩下的慢慢补。。

 


 

小改了一下,把C过了,发现是每组数据结束之后数组清零写的有问题(rnm退钱)

 

C.

题意:给2n(1e3)个数(大小范围为1到1e6),每一次可以选定两个数进行消去,要求他们的和为x,并且在执行完一次消去操作之后,将x由两个消去的数中较大的那个来替代。问这个数列是否可以完成这样的消去操作,如果可以的话,给出初始的x以及每一次操作所消去的两个数是什么

 

分析:首先证明,如果存在这样的方案,则每一次的消去操作,必须包含当前剩下的数当中的最大的那一个。因为如果不包含它,那么得到的x一定会小于它,所以它永远消去不了。得到这个结论之后,我们可以自定初始的x,这意味着,在第一次消去了最大数的同时,我们还可以任意消去任意的2n-1个数当中的某个。所以我们枚举这个数,之后后面的消去都是固定的,即选择剩下最大的那个amax以及x-amax来进行消去,如果x-amax不存在,则这组数据无法进行删除。用一个大小为1e6的数组cnt来记录每个数的出现次数,从而O(1)找到x-amax,总的时间复杂度是O(n2)

 

代码:

 1 int a[2010];
 2 int cnt[1000010];
 3 
 4 struct node
 5 {
 6     int x, y;
 7 };
 8 
 9 queue <node> q;
10 
11 int main()
12 {
13     int T = 1;
14     T = read();
15     while (T --)
16     {
17         int n;
18         n = read();
19         for (int i = 1; i <= 2 * n; i ++)
20             a[i] = read();
21         sort (a + 1, a + 2 * n + 1);
22         bool flag = false;
23         for (int i = 1; i < 2 * n; i ++)
24         {
25             for (int j = 1; j < 2 * n; j ++)
26             {
27                 if (i == j) continue;
28                 cnt[a[j]] ++;
29             }
30             while (!q.empty()) q.pop();
31             int mx = a[2 * n];
32             int ans = 1, d = 2 * n - 1;
33             node t;
34             t.x = a[i]; t.y = a[2 * n];
35             q.push(t);
36             while (ans < n && d > 0)
37             {
38                 if (cnt[a[d]] == 0)
39                 {
40                     d --;
41                     continue;
42                 }
43                 cnt[a[d]] --;
44                 int temp = mx - a[d];
45                 if (cnt[temp])
46                 {
47                     cnt[temp] --;
48                     t.x = temp; t.y = a[d];
49                     q.push(t);
50                     ans ++;
51                     mx = a[d];
52                     d --;
53                 }
54                 else
55                     break;
56             }
57             for (int j = 1; j <= 2 * n; j ++)
58                 cnt[a[j]] = 0;
59             if (ans == n)
60             {
61                 flag = true;
62                 break;
63             }
64             
65         }
66         if (!flag) printf ("NO\n");
67         else
68         {
69             printf ("YES\n");
70             node now = q.front();
71             printf ("%d\n", now.x + now.y);
72             for (int i = 1; i <= n; i ++)
73             {
74                 now = q.front(); q.pop();
75                 printf ("%d %d\n", now.x, now.y);
76             }
77         }
78     }
79     return 0;
80 }
C