CF779div2A-D1
一、A题
(1)题目描述

(2)解题思路
这个题就是一个模拟题,如果我当前位置为0,那么我试着往下找1,找到连续的一串1,如果连续的这串一的个数大于等于2个的话,我的答案就不用改变,否则我就需要加上2 - sum(连续的一的个数),然后直到结尾就可以了。
(3)代码实现
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 t; 45 int main() 46 { 47 cin >> t; 48 while(t--){ 49 int n; 50 n = read(); 51 string s; 52 cin >> s; 53 int ans = 0; 54 for(int i = 0,len = s.size();i < len;){ 55 bool ok = false; 56 if(s[i] == '0'){ 57 int j = i + 1; 58 int sum = 0; 59 while(j < len && s[j] == '1'){ 60 sum++; 61 j++; 62 } 63 if(j == len){ 64 ok = true; 65 break; 66 } 67 if(sum <= 1) 68 ans += 2-sum; 69 i = j; 70 } 71 else 72 i++; 73 if(ok) 74 break; 75 } 76 cout << ans << endl; 77 } 78 79 return 0; 80 }
二、B题
(1)题目描述

(2)解题思路
首先如果n为奇数答案肯定是0,为什么呢?因为n为奇数,那么在1-n中奇数的个数大于偶数,而奇数和偶数的gcd为1,是不可能大于1的,所以输出0
如果n为偶数的话,那么我对于每个奇数和偶数都有不同的排列,也就是奇数p^(n/2),偶数也是p(n/2),最后答案就是两个数相乘,记得求排列的时候求个模,最后答案的时候也要求个模。
(3)代码实现
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 const int mod = 998244353; 45 int main() 46 { 47 int t; 48 cin >> t; 49 while(t--){ 50 int n; 51 n = read(); 52 if(n & 1){ 53 cout << 0 << endl; 54 continue; 55 } 56 ll result = 1; 57 for(int i = 1;i <= n / 2;i++){ 58 result = (result * i) % mod; 59 } 60 if(result == 1){ 61 cout << 1 << endl; 62 continue; 63 } 64 else{ 65 cout << (result % mod * result % mod) % mod << endl; 66 } 67 } 68 return 0; 69 }
三、C题
(1)题目描述
(2)解题思路
这个题的题意是给你一个序列,表示循环右移i位,看能不能得到第a[i]段序列。
第一点就是这个题的话我刚开始没有想到1不能有0个,我只想到了1最多有一个,但是其实我是错的。因为每个构造得序列总会有个最大值会排到最前面,因此总会有1的存在。但是最大值最多只有一次出现在最前面,因此不可能出现多个1的情况。
第二点就是a[i + 1] - a[i] <= 1为什么呢?因为我后面的当最前面的时候,如果是最小的,而这个最小的肯定会被别的数融为一组,因此最小的数放到最前面,顶多就是加1。其他情况只会减少,或者抵消的情况。
(3)代码实现
1 #include "bits/stdc++.h" 2 using namespace std; 3 int n; 4 int a[101000]; 5 void solve() 6 { 7 int n; 8 cin >> n; 9 vector <int> ans(n); 10 for(auto &u:ans) 11 cin >> u; 12 for(int i = 0;i < n;i++){ 13 if(ans[(i + 1)%n] - ans[i] > 1){ 14 cout << "No" << endl; 15 return ; 16 } 17 } 18 if(!count(ans.begin(),ans.end(),1) || count(ans.begin(),ans.end(),1) >1) 19 cout << "No" << endl; 20 else 21 cout << "Yes" << endl; 22 } 23 int main() 24 { 25 int q; 26 cin >> q; 27 while(q--){ 28 solve(); 29 } 30 return 0; 31 }
四、D1题
(1)题目描述

(2)解题思路
这个题比赛的时候忘记关流,然后和C混着用了,直接不明不白Wa第一个点。后面比赛完后才知道这个细节。
这个题的题意就是让你构造一个数,使得存在某一个l-r区间的数异或上这个数等于他给出的序列
第一点:这个题我们考虑高位开始,如果这一位1的个数大于0的个数的话,我们的答案就加上(1<<i)为什么呢?因为我们如果1的个数多,表示这个位置的值最大可能是1,因为异或这个值后该位置为1的边0了,该位置为0的就变1了。而原序列是我们可以任意构造得。原序列这个位置为0的个数一定会大于等于1,故拿1比较好。
第二点:如果这一位的0的个数大于等于1的个数的话,我们的答案就不变,因为加0等于没加嘛。
最后加起来的值就是我们的答案啦!
(3)代码实现
1 #include "bits/stdc++.h" 2 using namespace std; 3 int n; 4 int a[101000]; 5 void solve() 6 { 7 int n; 8 cin >> n; 9 vector <int> ans(n); 10 for(auto &u:ans) 11 cin >> u; 12 for(int i = 0;i < n;i++){ 13 if(ans[(i + 1)%n] - ans[i] > 1){ 14 cout << "No" << endl; 15 return ; 16 } 17 } 18 if(!count(ans.begin(),ans.end(),1) || count(ans.begin(),ans.end(),1) >1) 19 cout << "No" << endl; 20 else 21 cout << "Yes" << endl; 22 } 23 int main() 24 { 25 int q; 26 cin >> q; 27 while(q--){ 28 solve(); 29 } 30 return 0; 31 }
本文来自博客园,作者:{scanner},转载请注明原文链接:{https://home.cnblogs.com/u/scannerkk/}

浙公网安备 33010602011771号