CF780Div3A-D

一、A题

  

 

   题意:给你两个数,第一个数表示1的个数,第二个数表示2的个数,现在问你最小不能表示的数是多少。

      如果1为0的话,那么肯定1就是答案

      如果1不为0的话,那么肯定是2的个数*2 + 1的个数,因为不论你怎么用2去凑,只要有1,那么奇数和偶数都能凑出来,因此最小不能凑出来就是2*2的个数+1的个数

  代码实现

 1 #include "bits/stdc++.h"
 2 #define PII pair<int,int>
 3 #define rep(i,z,n) for(int i = z;i <= n; i++)
 4 #define per(i,n,z) for(int i = n;i >= z; i--)
 5 #define ll long long
 6 #define db double
 7 #define vi vector<int>
 8 #define debug(x) cerr << "!!!" << x << endl;
 9 using namespace std;
10 //从某个串中把某个子串替换成另一个子串
11 string& replace_all(string& src, const string& old_value, const string& new_value) {
12     // 每次重新定位起始位置,防止上轮替换后的字符串形成新的old_value
13     for (string::size_type pos(0); pos != string::npos; pos += new_value.length()) {
14         if ((pos = src.find(old_value, pos)) != string::npos) {
15             src.replace(pos, old_value.length(), new_value);
16         }
17         else break;
18     }
19     return src;
20 }
21 inline ll read()
22 {
23     ll s,r;
24     r = 1;
25     s = 0;
26     char ch = getchar();
27     while(ch < '0' || ch > '9'){
28         if(ch == '-')
29             r = -1;
30         ch = getchar();
31     }
32     while(ch >= '0' && ch <= '9'){
33         s = (s << 1) + (s << 3) + (ch ^ 48);
34         ch = getchar();
35     }
36     return s * r;
37 }
38 inline void write(ll x)
39 {
40     if(x < 0) putchar('-'),x = -x;
41     if(x > 9) write(x / 10);
42     putchar(x % 10 + '0');
43 }
44 int main()
45 {
46     int t;
47     cin >> t;
48     while(t--){
49         ll a,b;
50         cin >> a >> b;
51         if(!a)
52             cout << 1 << endl;
53         else {
54             cout << b * 2 + a + 1 << endl;
55         }
56     }
57     return 0;
58 }

 

二、B题

  

 

   题意:给定你i种不同的蛋糕的数量,每次都选择数量最大的哪一种,但是又不让连续吃同一种蛋糕,所以我们只需要判断一下最大的是否大于次大的2个,如果大于等于,那么肯定就是NO,如果只有1个,大于等于2,也是NO,其他情况就是YES

  代码实现

 1 #include "bits/stdc++.h"
 2 #define PII pair<int,int>
 3 #define rep(i,z,n) for(int i = z;i <= n; i++)
 4 #define per(i,n,z) for(int i = n;i >= z; i--)
 5 #define ll long long
 6 #define db double
 7 #define vi vector<int>
 8 #define debug(x) cerr << "!!!" << x << endl;
 9 using namespace std;
10 //从某个串中把某个子串替换成另一个子串
11 string& replace_all(string& src, const string& old_value, const string& new_value) {
12     // 每次重新定位起始位置,防止上轮替换后的字符串形成新的old_value
13     for (string::size_type pos(0); pos != string::npos; pos += new_value.length()) {
14         if ((pos = src.find(old_value, pos)) != string::npos) {
15             src.replace(pos, old_value.length(), new_value);
16         }
17         else break;
18     }
19     return src;
20 }
21 inline ll read()
22 {
23     ll s,r;
24     r = 1;
25     s = 0;
26     char ch = getchar();
27     while(ch < '0' || ch > '9'){
28         if(ch == '-')
29             r = -1;
30         ch = getchar();
31     }
32     while(ch >= '0' && ch <= '9'){
33         s = (s << 1) + (s << 3) + (ch ^ 48);
34         ch = getchar();
35     }
36     return s * r;
37 }
38 inline void write(ll x)
39 {
40     if(x < 0) putchar('-'),x = -x;
41     if(x > 9) write(x / 10);
42     putchar(x % 10 + '0');
43 }
44 ll a[200010];
45 bool cmp(ll p,ll k)
46 {
47     return p < k;
48 }
49 int main()
50 {
51     int t;
52     cin >> t;
53     while(t--){
54         int n;
55         ll md = -1e9;
56         n = read();
57         rep(i,1,n) {a[i] = read();md = max(md,a[i]);}
58         sort(a + 1,a + 1 + n,cmp);
59         if(a[n] - a[n - 1] >= 2 || (n == 1 && a[1] >= 2))
60             cout << "NO" << endl;
61         else
62             cout << "YES"<< endl;
63     }
64     return 0;
65 }

 

三、C题

  

 

   题意:给你一个字符串,问你移除多少个字符后,改字符串奇数上的a[i] = a[i + 1],并且字符串长度为偶数。这题我们很好想到就是要循环删除,但是要怎么删除呢?我们用一个multiset记录当前是否存在两个相同的字符,如果存在,那么答案就加上当前multiset里面的长度-2,为什么这样可以呢?

  我们考虑两种情况

    第一种  

        

 

       如果删这两个c我删的是一个,如果我让aa配对,我删的是cc,那么我删了两个。所以我应该选择先删cc,也就是最先满足两个的

 

    第二种

      

 

     这里我们如果选择了aa那我们至少要删两个,bb我们至少要删3个,因此我们应该选择aa,所以我们的贪心策略是正确的,选择最早满足2个的字符。

  代码实现

 1 #include "bits/stdc++.h"
 2 #define PII pair<int,int>
 3 #define rep(i,z,n) for(int i = z;i <= n; i++)
 4 #define per(i,n,z) for(int i = n;i >= z; i--)
 5 #define ll long long
 6 #define db double
 7 #define vi vector<int>
 8 #define debug(x) cerr << "!!!" << x << endl;
 9 using namespace std;
10 //从某个串中把某个子串替换成另一个子串
11 string& replace_all(string& src, const string& old_value, const string& new_value) {
12     // 每次重新定位起始位置,防止上轮替换后的字符串形成新的old_value
13     for (string::size_type pos(0); pos != string::npos; pos += new_value.length()) {
14         if ((pos = src.find(old_value, pos)) != string::npos) {
15             src.replace(pos, old_value.length(), new_value);
16         }
17         else break;
18     }
19     return src;
20 }
21 inline ll read()
22 {
23     ll s,r;
24     r = 1;
25     s = 0;
26     char ch = getchar();
27     while(ch < '0' || ch > '9'){
28         if(ch == '-')
29             r = -1;
30         ch = getchar();
31     }
32     while(ch >= '0' && ch <= '9'){
33         s = (s << 1) + (s << 3) + (ch ^ 48);
34         ch = getchar();
35     }
36     return s * r;
37 }
38 inline void write(ll x)
39 {
40     if(x < 0) putchar('-'),x = -x;
41     if(x > 9) write(x / 10);
42     putchar(x % 10 + '0');
43 }
44 void solve(string s)
45 {
46     multiset <char> mp;
47     mp.clear();
48     int res = 0;
49     for(int i = 0,len = s.size();i < len;i++){
50         mp.insert(s[i]);
51         if(mp.count(s[i]) == 2){
52             res += mp.size() - 2;
53             mp.clear();
54         }
55     }
56     res += mp.size();
57     cout << res << endl;
58 }
59 int main()
60 {
61     int t;
62     cin >> t;
63     while(t--){
64         string s;
65         cin >> s;
66         solve(s);
67     }
68     return 0;
69 }

 

四、D题

  

 

   题意:给定你n个数字,他们的绝对值都小于等于2,现在问你你可以从左边开始或者从右边开始删除,问你这样做任意次后这串数字的最大乘积是多少,打印左边和右边删除的数字的个数。

  

  解题思路大概就是

  1.把整个数组用0分隔

  2.把0左边的和0这个位置的负数统计,如果负数为偶数,那么就统计答案,也就是统计2的个数,因为1不影响乘积

  3.如果0左边的负数的奇数,那么我们分别删除左边第一个奇数,判断一次答案;再删除右边的一个负数,判断一次答案。用cnt记录2的个数,用来更新答案

  

  代码实现

  1 #include "bits/stdc++.h"
  2 #define PII pair<int,int>
  3 #define rep(i,z,n) for(int i = z;i <= n; i++)
  4 #define per(i,n,z) for(int i = n;i >= z; i--)
  5 #define ll long long
  6 #define db double
  7 #define vi vector<int>
  8 #define debug(x) cerr << "!!!" << x << endl;
  9 using namespace std;
 10 //从某个串中把某个子串替换成另一个子串
 11 string& replace_all(string& src, const string& old_value, const string& new_value) {
 12     // 每次重新定位起始位置,防止上轮替换后的字符串形成新的old_value
 13     for (string::size_type pos(0); pos != string::npos; pos += new_value.length()) {
 14         if ((pos = src.find(old_value, pos)) != string::npos) {
 15             src.replace(pos, old_value.length(), new_value);
 16         }
 17         else break;
 18     }
 19     return src;
 20 }
 21 inline ll read()
 22 {
 23     ll s,r;
 24     r = 1;
 25     s = 0;
 26     char ch = getchar();
 27     while(ch < '0' || ch > '9'){
 28         if(ch == '-')
 29             r = -1;
 30         ch = getchar();
 31     }
 32     while(ch >= '0' && ch <= '9'){
 33         s = (s << 1) + (s << 3) + (ch ^ 48);
 34         ch = getchar();
 35     }
 36     return s * r;
 37 }
 38 inline void write(ll x)
 39 {
 40     if(x < 0) putchar('-'),x = -x;
 41     if(x > 9) write(x / 10);
 42     putchar(x % 10 + '0');
 43 }
 44 int a[200010];
 45 int n;
 46 int cnt;
 47 int x,y;
 48 int cnt_neg(int L,int R)
 49 {
 50     int num = 0;
 51     for(int i = L;i <= R;i++)
 52         if(a[i] < 0) 
 53             num++;
 54     return num;
 55 }
 56 void upd(int L,int R)
 57 {
 58     if(L > R)
 59         return;
 60     int num = 0;
 61     for(int i = L;i <= R;i++)
 62         if(abs(a[i]) == 2)
 63             num++;
 64     if(num > cnt) {cnt = num;x = L - 1;y = n - R;}
 65 }
 66 void cal(int L,int R)
 67 {
 68     int sign = cnt_neg(L,R);
 69     if(sign & 1) {
 70         int id = L;
 71         while(a[id] > 0)
 72             id++;
 73         upd(L,id - 1);
 74         upd(id + 1,R);
 75         id = R;
 76         while(a[id] > 0)
 77             id--;
 78         upd(L,id - 1);
 79         upd(id + 1,R);
 80     }
 81     else upd(L,R);
 82 }
 83 void solve()
 84 {
 85     x = 0;
 86     y = n;
 87     cnt = 0;
 88     a[n + 1] = 0;
 89     for(int i = 1,j = 1;i <= n + 1;i++) {
 90         if(a[i] == 0){
 91             cal(j,i - 1);
 92             j = i + 1;
 93         }
 94     }
 95     cout << x << ' ' << y << endl;
 96 }
 97 int main()
 98 {
 99     int t;
100     cin >> t;
101     while(t--){
102         n = read();
103         rep(i,1,n) a[i] = read();
104         solve();
105     }
106     return 0;
107 }
posted @ 2022-04-01 21:08  scannerkk  阅读(26)  评论(0)    收藏  举报