Codeforces Round #521 (Div. 3) CDE
C
问删掉在数组中一个数后,剩下的数组中,是否存在一个数时其它所有数的和。
遍历每一个数,假设删掉它后,剩下的数中取一个最大值,看他的值是不是数组之和的一半,是的话就成立。
1 #include <bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const int N = 2e5+10; 5 ll a[N], n; 6 vector<ll> v; 7 int main() { 8 cin >> n; 9 ll sum = 0; 10 priority_queue<ll> que; 11 for(int i = 1; i <= n; i ++) cin >> a[i], sum += a[i], que.push(a[i]); 12 int ans = 0; 13 // cout << sum << ' ' << que.top() << endl; 14 for(int i = 1; i <= n; i ++) { 15 if(que.top() == a[i]) { 16 que.pop(); 17 sum -= a[i]; 18 if(sum == que.top()*2) ans++, v.push_back(i); 19 sum += a[i]; 20 que.push(a[i]); 21 } else { 22 sum -= a[i]; 23 if(sum == que.top()*2) ans++, v.push_back(i); 24 sum += a[i]; 25 } 26 } 27 printf("%d\n",ans); 28 for(auto x : v) printf("%lld ", x);printf("\n"); 29 return 0; 30 }
D
有一个数组,可以选定一个子集,看最大能删除多少次,输出那个子集。
二分,检查当前最大删除次数时m时,是否成立。
1 #include <bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const int N = 2e5+10; 5 int a[N], n, k, x; 6 bool cmp(int x, int y) { return x > y;} 7 bool ok(int m) { 8 int ans = 0; 9 for(int i = 0; i < N; i ++) if(a[i])ans += a[i]/m; 10 return ans >= k; 11 } 12 int main() { 13 cin >> n >> k; 14 for(int i = 1; i <= n; i ++) { 15 cin >> x; 16 a[x]++; 17 } 18 int l = 1, r = n/k, MAX = 0; 19 while (l <= r) { 20 int m = (l+r) >> 1; 21 if(ok(m)) { 22 MAX = max(MAX, m); 23 l = m + 1; 24 } else r = m-1; 25 } 26 int ans = 0; 27 for(int i = 0; i < N; i ++) { 28 for(int j = 0; j < a[i]/MAX; j ++) { 29 if(ans == k) break; 30 printf("%d%c",i," \n"[ans==k-1]); 31 ans ++; 32 } 33 } 34 return 0; 35 }
E
有很多主题,每个主题都有一些题目,选定一些主题,后面主题的问题数一定时前面的两倍,第一个主题的问题数随意,求最大的问题数。
第一个主题的问从1个开始计算,一直到最多的问题。每次算出来问题总数后求最大值即可。
1 #include <bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const int N = 2e5+10; 5 int x, n, a[N], cnt; 6 map<int,int> mp; 7 bool vis[N]; 8 int main() { 9 cin >> n; 10 for(int i = 1; i <= n; i ++) cin >> x, mp[x]++; 11 for(auto m : mp) a[cnt++] = m.second; 12 sort(a,a+cnt); 13 int MAX = 0; 14 for(int i = 1; i <= a[cnt-1]; i ++) { 15 int x = i, ans = 0, l = 0, r = cnt; 16 while(1) { 17 int id = lower_bound(a+l,a+cnt,x)-a; 18 if(id >= cnt) break; 19 ans += x; 20 l = id+1; 21 x *= 2; 22 } 23 MAX = max(MAX, ans); 24 } 25 printf("%d\n",MAX); 26 return 0; 27 }