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 }
本文来自博客园,作者:{scanner},转载请注明原文链接:{https://home.cnblogs.com/u/scannerkk/}