Codeforces Round #577 (Div. 2) 题解

比赛链接:https://codeforc.es/contest/1201

A. Important Exam
题意:有\(n\)个人,每个人给出\(m\)个答案,每个答案都有一个分值\(a_i\),每个问题的正确答案不确定,询问最大可能的得分为多少。

分析:对于每个问题贪心最大数量就好。

AC代码:

#include <bits/stdc++.h>
#define SIZE 500007
#define rep(i, a, b) for(int i = a; i <= b; ++i)
using namespace std;
typedef long long ll;
void io() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
}
int n, m, t; 
string s;
map<char, int>mp[1005];
int main() {
	io(); cin >> n >> m;
	rep(i, 1, n) {
		cin >> s;
		rep(j, 0, s.length() - 1) {
			mp[j + 1][s[j] - 'a']++;
		}
	}
	ll ans = 0;
	rep(i, 1, m) {
		cin >> t;
		int maxx = 0;
		for (auto it : mp[i]) {
			maxx = max(maxx, it.second);
		}
		ans += 1ll * maxx * t;
	}
	cout << ans;
}

 
B. Zero Array
题意:给出一个\(n\)个数的数列,每次操作能将其中任意两个数\(-1\),询问能否将这个数列全部减为零。

分析:首先由于每次减少的总数为2,因此和为奇数的数列不行。再考虑和为偶数的数列,发现当且仅当最大的数值大于数列总和的一半时不存在。

AC代码:

#include <bits/stdc++.h>
#define SIZE 500007
#define rep(i, a, b) for(int i = a; i <= b; ++i)
using namespace std;
typedef long long ll;
void io() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
}
int n, m, t; 
ll a[SIZE];
int main() {
	io(); cin >> n;
	ll sum = 0;
	rep(i, 1, n) {
		cin >> a[i];
		sum += a[i];
	}
	sort(a + 1, a + 1 + n);
	if (sum & 1) { cout << "NO"; return 0; }
	else {
		if (a[n] > sum / 2)cout << "NO";
		else cout << "YES";
	}
}

 
C. Maximum Median
题意:给定一个\(n\)个数的数列和\(k\)次操作,每次能将数列中的一个数\(+1\)。询问\(k\)次操作后数列中位数的最大值为多少。(\(n\)为奇数)

分析:先排序,然后为了使中位数最大,我们显然只用对当前数列中位数及中位数之后的数进行操作。于是我们考虑贪心地加,下面举个例子:

7 7
1 2 3 4 5 6 10

第一步:1 2 3 5 5 6 10

第二步:1 2 3 6 6 6 10

第三步:1 2 3 7 7 8 10

这种贪心的构造通过一种类似于前缀和的想法即可实现,AC代码:

#include <bits/stdc++.h>
#define SIZE 500007
#define rep(i, a, b) for(int i = a; i <= b; ++i)
using namespace std;
typedef long long ll;
void io() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
}
int n, m, t, k;
ll a[SIZE], pre[SIZE];
int main() {
	io(); cin >> n >> k;
	rep(i, 1, n) cin >> a[i];
	sort(a + 1, a + 1 + n);
	rep(i, (n + 3) / 2, n) {
		pre[i] = pre[i - 1] + (i - (n + 1) / 2) * (a[i] - a[i - 1]);
		if (pre[i] > k) {
			ll tmp = ((k - pre[i - 1]) / (i - (n + 1) / 2));
			cout << a[i - 1] + tmp;
			return 0;
		}
	}
	ll tmp = (k - pre[n]) / ((n + 1) / 2);
	cout << tmp + a[n];
}

 
D题下午打完多校再写吧。。。
upd:咕咕咕

posted @ 2019-08-05 10:39  st1vdy  阅读(163)  评论(0编辑  收藏  举报