题目链接:https://codeforces.com/contest/1251
A. Broken Keyboard
题意:俩种按键,好的按键按一次出现一个字符C,坏的按一次连续出现俩个相同的字符C,问好的按键有哪些。
思路:出现过连续出现次数为奇数的字符可以认定为好的。

1 #include<bits/stdc++.h> 2 using namespace std; 3 int main() 4 { 5 std::ios::sync_with_stdio(false); 6 int t; 7 cin >> t; 8 while(t--) 9 { 10 char s[1000]; 11 cin >> s; 12 int vis[50] = {0}; 13 int cnt = 1; 14 int n = strlen(s); 15 if(n == 1){ 16 cout << s[0] << endl; 17 continue; 18 } 19 20 for(int i = 1;i <= n;i++){ 21 if(s[i] == s[i - 1]) cnt++; 22 else{ 23 int t = s[i - 1] - 'a'; 24 if(cnt % 2) vis[t] = 1; 25 cnt = 1; 26 } 27 } 28 for(int i = 0;i <= 26;i++){ 29 if(vis[i]){ 30 cout << (char)(i + 'a'); 31 } 32 } 33 cout << endl; 34 } 35 return 0; 36 }
B. Binary Palindromes
思路:答案要么为n要么为n-1,因为你可以牺牲一个串来使其他串达到回文,考虑最后一个串,如果是奇数串那么肯定回文,答案为n,如果是偶数串只要判断1或0出现的次数的奇偶性就行。

1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 3e5 + 5l; 4 int a[maxn], b[maxn]; 5 int cnt1 = 0, cnt2 = 0; 6 int main() 7 { 8 std::ios::sync_with_stdio(false); 9 int t; 10 cin >> t; 11 while(t--) 12 { 13 string s[100]; 14 int n; 15 cin >> n; 16 int odd = 0, even = 0, num = 0; 17 for(int i = 0;i < n;i++){ 18 cin >> s[i]; 19 if(s[i].size() % 2 == 0){ 20 even++; 21 for(int j = 0;j < s[i].size();j++) 22 if(s[i][j] == '1') num++; 23 } 24 else odd++; 25 } 26 if(odd){ 27 cout << n << endl; 28 } 29 else{ 30 if(num%2) cout << n - 1 << endl; 31 else cout << n << endl; 32 } 33 } 34 return 0; 35 }
C. Minimize The Integer
思路:易得相邻奇数无法交换,可知奇数之间相对位置不变,偶数也是这样,所以奇数偶数分开成俩串,依次从俩串的头挑小的数字加入。

1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 3e5 + 5l; 4 int a[maxn], b[maxn]; 5 int cnt1 = 0, cnt2 = 0; 6 int main() 7 { 8 std::ios::sync_with_stdio(false); 9 int t; 10 cin >> t; 11 while(t--) 12 { 13 string s; 14 cin >> s; 15 for(int i = 0;i < s.size();i++) 16 { 17 int x = s[i] - '0'; 18 if(x % 2) a[cnt1++] = x; 19 else b[cnt2++] = x; 20 } 21 int pos1 = 0, pos2 = 0; 22 while(cnt1 + cnt2){ 23 if(a[pos1] < b[pos2]){ 24 if(cnt1) cout << a[pos1++],cnt1--; 25 else cout << b[pos2++],cnt2--; 26 } 27 else { 28 if(cnt2)cout << b[pos2++],cnt2--; 29 else cout << a[pos1++],cnt1--; 30 } 31 } 32 cout << endl; 33 } 34 return 0; 35 }
D. Salary Changing
思路:二分可行中位数最大值,贪心检查答案。

1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 2e5 + 50; 5 struct node{ 6 ll l, r; 7 }; 8 node a[maxn]; 9 ll s; 10 int n; 11 bool cmp(const node &a,const node &b){ 12 if(a.l == b.l) return a.r > b.r; 13 else return a.l > b.l; 14 } 15 bool check(ll mid) 16 { 17 ll ans = 0; 18 int pos = n / 2 + 1; 19 for(int i = 1;i <= n;i++) 20 { 21 if(a[i].r >= mid && pos ){ 22 ans += max(a[i].l, mid); 23 pos--; 24 } 25 else{ 26 ans += a[i].l; 27 } 28 } 29 return (ans <= s && !pos); 30 } 31 int main() 32 { 33 std::ios::sync_with_stdio(false); 34 int t; 35 cin >> t; 36 while(t--) 37 { 38 cin >> n >> s; 39 for(int i = 1;i <= n;i++) 40 { 41 cin >> a[i].l >> a[i].r; 42 } 43 sort(a + 1, a + n + 1, cmp); 44 ll l = 0, r = 1e9 + 1, o = 0; 45 while(l <= r) 46 { 47 ll mid = (l +r) >> 1; 48 if(check(mid)) o = mid,l = mid + 1; 49 else r = mid - 1; 50 } 51 cout << o << endl; 52 } 53 return 0; 54 }
E2. Voting (Hard Version)
思路:贪心,我们可以从m大的人中开始挑前几个p最小的。

1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 2e5 + 50; 5 vector<ll> G[maxn]; 6 priority_queue<ll, vector<ll>, greater<ll> > q; 7 int main() 8 { 9 std::ios::sync_with_stdio(false); 10 int t; 11 cin >> t; 12 while(t--) 13 { 14 int n; 15 cin >> n; 16 int p, m; 17 for(int i = 0;i < n;i++) G[i].clear(); 18 for(int i = 0;i < n;i++) 19 { 20 cin >> m >> p; 21 G[m].push_back(p); 22 } 23 ll ans = 0; 24 for(int i = n - 1;i >= 0;i--){ 25 for(int j = 0;j < G[i].size();j++){ 26 q.push(G[i][j]); 27 } 28 while(q.size() > n - i) ans += q.top(),q.pop(); 29 } 30 while(!q.empty()) q.pop(); 31 cout << ans << endl; 32 } 33 return 0; 34 }