CF778div1+div2(A-C)
阿新 • • 發佈:2022-03-24
一、A題
題目意思是我做一次把某個區間逆轉的操作,然後輸出可能得到的最大的相鄰兩數之和。很明顯,這個題無論如何都能讓最大的和次大的兩個數相加。因此我們只需要排個序,然後輸出最大兩個數的和就行了。
程式碼實現
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_value13 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[1010]; 45 int main() 46 { 47 int t; 48 cin >> t; 49 while(t--){ 50 int n; 51 n = read(); 52 rep(i,1,n) 53 a[i] = read(); 54 sort(a + 1,a + 1 + n); 55 cout << a[n] + a[n - 1] << endl; 56 } 57 return 0; 58 }
二、B題
解題思路
這個題讓你不斷的刪除字元,直到某個字元在這個字元的後面的沒有出現時,我們就停止刪除。很明顯我們可以記錄某個字元的位置,從頭掃到位,判斷是否是最後一位,如果是最後一位了,那麼這個字元和這個字元後面的都算作答案串了。
程式碼實現
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 string s; 50 cin >> s; 51 int vis[30]; 52 int len = s.size(); 53 memset(vis,0,sizeof(vis)); 54 for(int i = 0;i < len;i++) 55 vis[s[i] - '0'] = i; 56 string ans; 57 for(int i = 0;i < len;i++){ 58 if(vis[s[i] - '0'] <= i){ 59 int j = i; 60 while(j < len){ 61 ans += s[j]; 62 j++; 63 } 64 break; 65 } 66 } 67 cout << ans << endl; 68 } 69 return 0; 70 }
三、C題
解題思路
這個題問你是否存在一個數,能經過他說的兩個操作轉化為他給的目標序列。
如果正著推最後一個數是否存在,這明顯不可能。
這時候我們假裝答案存在,並且最後是sum,我們看是否能經過這些操作得到目標序列
我們用兩個multiset記錄目標串和列舉串。
列舉串初始化為sum
目標串是輸入的串
我們每次列舉如果是奇數我可以進行的到sum / 2和sum / 2 + 1的數字
當我們的sum小於目標串的最大值時,肯定就不可以列舉到目標串了,就可以直接退出迴圈,或者我們把目標串列舉完了,也可以退出迴圈。
最後如果目標串的沒有被消除的話就輸出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 int n; 45 multiset <ll> mp1; 46 multiset <ll> mp2; 47 int main() 48 { 49 int t; 50 t = read(); 51 while(t--){ 52 ll sum = 0; 53 n = read(); 54 mp1.clear(); 55 mp2.clear(); 56 rep(i,1,n) { 57 ll d; 58 d = read(); 59 sum += d; 60 mp1.insert(d); 61 } 62 if(n == 1){ 63 cout << "YES" << endl; 64 continue; 65 } 66 mp2.insert(sum); 67 for(auto iter = mp2.rbegin();!mp1.empty();iter = mp2.rbegin()){ 68 if(*iter < *(mp1.rbegin())) 69 break; 70 if(mp1.count(*iter)){ 71 mp1.erase(mp1.lower_bound(*iter)); 72 mp2.erase(mp2.lower_bound(*iter)); 73 continue; 74 } 75 mp2.insert((*iter + 1) / 2); 76 mp2.insert(*iter / 2); 77 mp2.erase(mp2.lower_bound(*iter)); 78 } 79 if(mp1.empty()) 80 cout << "YES" << endl; 81 else 82 cout << "NO" << endl; 83 } 84 return 0; 85 }