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 }

 

有一个数组,可以选定一个子集,看最大能删除多少次,输出那个子集。

二分,检查当前最大删除次数时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 }

 

posted @ 2018-11-17 12:00  starry_sky  阅读(217)  评论(0编辑  收藏  举报