AtCoder Beginner Contest 173 题解

这场咋全是结论题啊?

A - Payment

难得有心情写A的题解

就一思博题,是1000的倍数就输出0不是就输出最近的1000的倍数减去它。

#include 
using namespace std;
int n;
int main() {
	scanf("%d", &n);
	if (n % 1000 == 0) cout << 0;
	else cout << n / 1000 * 1000 + 1000 - n;
	return 0;
}

B - Judge Status Summary

map统计一遍就好。

#include 
using namespace std;
int n;
map mp;
string s;
int main() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> s;
		mp[s]++;
	}
	cout << "AC x " << mp["AC"] << endl;
	cout << "WA x " << mp["WA"] << endl;
	cout << "TLE x " << mp["TLE"] << endl;
	cout << "RE x " << mp["RE"] << endl;
	return 0;
}

C - H and V

刚一看题觉得这题很难,然后看一下数据范围...暴力就行

#include 
using namespace std;
int n, m, T;
char mp[10][10];
bool mark[10][10];
int ans;
int main() {
	cin >> n >> m >> T;
	for (int i = 1; i <= n; i++) {
		scanf("%s", mp[i] + 1);
	}
	for (int i = 0; i < (1 << n); i++) {
		for (int j = 0; j < (1 << m); j++) {
			memset(mark, 0, sizeof(mark));
			for (int k = 0; k < n; k++) {
				if ((i >> k) & 1) {
					for (int l = 1; l <= m; l++) {
						mark[k + 1][l] = 1;
					}
				}
			}
			for (int k = 0; k < m; k++) {
				if ((j >> k) & 1) {
					for (int l = 1; l <= n; l++) {
						mark[l][k + 1] = 1;
					}
				}
			}
			int cnt = 0;
			for (int k = 1; k <= n; k++) for(int l = 1; l <= m; l++) if (!mark[k][l] && mp[k][l] == '#') cnt++;
			if (cnt == T) ans++;
		}
	}
	cout << ans;
	return 0;
}

D - Chat in a Circle

不错的贪心题,按从大到小的排序,除了最大的其它都可以取两遍,取前n-1大即可。

#include 
using namespace std;
typedef long long ll;
const int N = 200010;
int n;
ll ans;
int a[N];
queue q;
int main() {
	cin >> n;
	for (int i = 1; i <= n; i++) cin >> a[i];
	sort(a + 1, a + 1 + n);
	q.push(a[n]);
	for (int i = n - 1; i; i--) {
		q.push(a[i]);
		q.push(a[i]);
	}
	for (int i = 1; i < n; i++) {
		ans += q.front();
		q.pop();
	}
	cout << ans;
	return 0;
}

E - Multiplication 4

又是贪心题。考场想歪浪费了好多时间。

先按abs排序取前k大然后看看是不是负数,如果是再考虑换一个数比较一下就行。

#include 
using namespace std;
typedef long long ll;
const int N = 200010;
const ll mod = 1e9 + 7;
struct node{
	ll val, f;
	friend bool operator < (node x, node y) {
		return x.val * x.f < y.val * y.f;
	}
};
int n, k, tmp;
ll a[N], ans = 1;
priority_queue q1, q2;
ll s1[N], s2[N], top1, top2;
int main() {
	cin >> n >> k;
	tmp = k;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		if (a[i] > 0) q1.push(node{a[i], 1});
		else q2.push(node{a[i], -1});
	}
	while (k) {
		if (!q1.empty() && !q2.empty()) {
			node x = q1.top();
			q1.pop();
			node y = q2.top();
			q2.pop();
			if (x.val * x.f > y.val * y.f) {
				s1[++top1] = x.val;
				q2.push(node{y.val, y.f});
			} else {
				s2[++top2] = y.val;
				q1.push(node{x.val, x.f});
			}
		} else if (!q1.empty()) {
			node x = q1.top();
			q1.pop();
			s1[++top1] = x.val;
		} else if (!q2.empty()) {
			node x = q2.top();
			q2.pop();
			s2[++top2] = x.val;
		}
		k--;
	}
	if (top2 % 2) {
		if (top1) {
			if (!q1.empty() && !q2.empty()) {
				if (q2.top().val * s2[top2] > q1.top().val * s1[top1]) {
					top1--;
					s2[++top2] = q2.top().val;
				} else {
					top2--;
					s1[++top1] = q1.top().val;
				}
			} else if (!q1.empty()) {
				top2--;
				s1[++top1] = q1.top().val;
			} else if (!q2.empty()) {
				top1--;
				s2[++top2] = q2.top().val;
			}
		} else {
			if (!q1.empty()) {
				top2--;
				s1[++top1] = q1.top().val;
			} else {
				sort(a + 1, a + n + 1);
				top2 = 0;
				for (int i = n; i >= n - tmp + 1; i--) {
					s2[++top2] = a[i];
				}
			}
		}
	}
	for (int i = 1; i <= top1; i++) ans = (ans * s1[i]) % mod;
	for (int i = 1; i <= top2; i++) ans = (ans * s2[i]) % mod;
	cout << (ans % mod + mod) % mod;
	return 0;
}

F - Intervals on Tree

又是结论题。

我们发现对于一条边它会把两个端点的连通块变成一个,所以先把树看成没有边的,每一条边减去有多少个区间包含其即可。

#include 
using namespace std;
typedef long long ll;
const int N = 200010;
const ll mod = 1e9 + 7;
int n;
ll ans;
int main() {
	cin >> n;
	for (ll i = 1; i <= n; i++) ans += i * (n - i + 1);
	for (int i = 1; i < n; i++) {
		ll u, v;
		cin >> u >> v;
		if (u > v) swap(u, v);
		ans -= u * (n - v + 1);
	}
	cout << ans;
	return 0;
}

你可能感兴趣的:(AtCoder Beginner Contest 173 题解)