CF767div2A-D

一、题目分析

 

A.Download More RAM

  题意是给定你初始内存,和n个软件,每次运行一个软件如果你能成功运行,你就能得到永久的内存,问你最后能得到的RAM最大值为多少

  按软件对内存的需求从小到大排个序,这样你能获得的永久内存越多

 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 struct node {
 4     int a,b;
 5 }c[1010];
 6 bool cmp(node a,node b)
 7 {
 8     return a.a < b.a;
 9 }
10 int main()
11 {
12     int t;
13     cin >> t;
14     while(t--){
15         int n,ans;
16         cin >> n >> ans;
17         for(int i = 0;i < n;i++)
18             cin >> c[i].a;
19         for(int i = 0;i < n;i++)
20             cin >> c[i].b;
21         sort(c,c + n,cmp);
22         for(int i = 0;i < n;i++)
23             if(ans >= c[i].a)
24                 ans += c[i].b;
25         cout << ans << endl;                 
26     }
27     return 0;
28 }

B. GCD Arrays

  题目要求给你一个区间【l,r】,每次你都可以选择两个数字然后相乘,代替原来的这两个数字,给定你最多的操作次数,问你能不能最后得到a的gcd大于1,如果不能输出NO,如果能输出YES

  我们考虑一下特殊情况1-1,这明显是不能的对吧?然后再看一下如果只有1个数字,那么只要是不等于1肯定gcd大于1,所以这是两种情况。

  最后考虑一种平常情况,要想gcd大于1,那么这个序列内的数是不能互质的,首先奇数和偶数一定是互质的,那么我们只需要考虑奇数和偶数的数量,奇数变成偶数至少要奇数的个数步,所以我们只需要统计区间内的奇数的个数即可。如果大于k那么则输出NO,否则输出YES

 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 int main()
 4 {
 5     int t;
 6     cin >> t;
 7     while(t--){
 8         int l,r,k;
 9         cin >> l >> r >> k;
10         if(l == r && l == 1){
11             cout << "NO" << endl;
12             continue;
13         }
14         if(r - l == 0 && l > 1){
15             cout << "YES" << endl;
16             continue;
17         }   
18         int ji;
19         if(l % 2 == 0 && r % 2 == 0)
20             ji = (r - l) / 2;
21         else if(l % 2 == 1 && r % 2 == 1)
22             ji = (r - l) / 2 + 1;
23         else 
24             ji = (r - l + 1) / 2;
25         if(ji > k)
26             cout << "NO" << endl;
27         else 
28             cout << "YES" << endl;
29     }
30     return 0;
31 }

C.Meximum Array

  题意是给定你一个序列,让你求这个序列的最大字典序的Mex(补集的最小值)集合,问在字典序最大能求的最大Mex集合长度为多少

  我们首先要拿一个数组记录出现的数字以及次数,然后用mex不断枚举最大值,什么时候结束呢,当mex的值不存在该数组中时,就可以结束枚举把答案放入ans数组中即可。最重要的是其中枚举mex的过程,用set可以实现更快的查询,我也是做完后看别人做的,也是学习了一波。

  

 1 #include "bits/stdc++.h"
 2 const int maxn = 2e5;
 3 int bucket[maxn+10];
 4 int a[maxn + 10];
 5 using namespace std;
 6 int main()
 7 {
 8     vector <int> ans;
 9     int t;
10     cin >> t;
11     while(t--){
12         int n;
13         ans.clear();
14         memset(bucket,0,sizeof(bucket));
15         cin >> n;
16         for(int i = 0;i < n;i++){
17             cin >> a[i];
18             bucket[a[i]]++;
19         }
20         int mex = 0;
21         set <int> vis;
22         for(int i = 0;i < n;i++){
23             vis.insert(a[i]);
24             bucket[a[i]]--;
25             while(vis.count(mex)) mex++;
26             if(!bucket[mex]){
27                 ans.push_back(mex);
28                 mex = 0;
29                 vis.clear();
30             }
31         }
32         cout << ans.size() << endl;
33         for(auto iter = ans.begin();iter != ans.end();iter++)
34             cout << *iter << ' ';
35         cout << endl;
36     }
37     return 0;
38 }

D.Peculiar Movie Preferences

  题意很简单,就是给定你n个字符串,问你能否在n个字符串中得到回文字符串,当然你也可以用前面的和后面的拼接起来组成回文串,不难发现这个回文串最多只能由两个字符串组成,然后你发现字符串本身也可能是回文串,有3种情况

  一、本身是回文串

  1.当字符串长度为1时

  2.长度为2时两个相等

  3.或者长度为3时,第一个和第三个相等

  

  二、拼接成的回文串(只能用前面的拼后面的)

  1.当前字符串长度为2时,能成回文的情况只有前面的串中有和它反过来的,或者说有长度为3的字符串,头两个和它是反过来的

  2.当前字符串长度为3是,能成回文的情况有前面有长度为3的字符串和它是反过来的,或者是前面有长度为2的,是当前字符串最后两个反过来的情况

  

  代码实现:

 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 char s[4];
 4 bool ans[27][27];
 5 bool ans2[27][27][27];
 6 int main()
 7 {
 8     int t;
 9     cin >> t;
10     while(t--){
11         int n;
12         scanf("%d",&n);
13         int flag = 0;
14         memset(ans,0,sizeof(ans));
15         memset(ans2,0,sizeof(ans2));
16         while(n--){
17             scanf("%s",s);
18             int len = strlen(s);
19             if(len == 1)
20                 flag = 1;
21             else if(len == 2){
22                 if(s[0] == s[1] || ans[s[1] - 'a'][s[0] - 'a'])
23                     flag = 1;
24                 else {
25                     for(int i = 0;i < 26;i++)
26                         if(ans2[s[1] - 'a'][s[0] - 'a'][i])
27                             flag = 1;
28                 }
29                 ans[s[0] - 'a'][s[1] - 'a'] = 1;
30             }
31             else {
32                 if(s[0] == s[2] || ans2[s[2] - 'a'][s[1] - 'a'][s[0] - 'a'] || ans[s[2] - 'a'][s[1] - 'a'])
33                     flag = 1;
34                 ans2[s[0] - 'a'][s[1] - 'a'][s[2] - 'a'] = 1;
35             }
36         }
37         cout << (flag ? "YES\n" : "NO\n");
38     }
39     return 0;
40 }

 

二、总结

  这场cf感觉打傻了自己,A题看题目的时候漏了个条件,wa了一发,C题当时没想到用set,D题T了两发,多多补题。

 
posted @ 2022-01-23 22:31  scannerkk  阅读(38)  评论(0)    收藏  举报