放假之后的第一天,打着玩,状态有点差,写了两个题,第三个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 }
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 }
刚回家,去做一个核酸,剩下的慢慢补。。
小改了一下,把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 }
浙公网安备 33010602011771号