【AtCoder ABC 99】补题AK

比赛链接

A 语法题

思路 判断一个数是否大于 999 。如果不大于,输出ABC,否则输出ABD。
代码
#include <bits/stdc++.h>
using namespace std;

int n;
int main() {
	cin >> n;

	if (n <= 999) cout << "ABC";
	else cout << "ABD";
	return 0;
}

B 数学

思路 两栋楼之间的距离 $x = b - a$

b的高度就是\(x * (x + 1) / 2\)

那么雪的高度既是\(ans = x * (x + 1) / 2 - b\)

代码
#include <bits/stdc++.h>
using namespace std;

int a, b;
int x;
int ans;
int main() {
	cin >> a >> b;

	x = b - a;
	ans = x * (x + 1) / 2 - b;

	cout << ans;
	return 0;
}

C 贪心 枚举/动态规划

思路

完全背包秒了
其实不用这么复杂,物品只有三个,其中的1只是凑数的,实际上就两种

对于每种分配方式,肯定有一部分是6,一部分是9

那么把n分成两部分,i和n-i,其中一部分用6,另外一部分用9,剩下的用1补齐(贪心优先选最大的)
那么最优答案肯定这其中,\(n<10^5\)枚举完全可以过

完全背包
#include <bits/stdc++.h>
using namespace std;
#define forn(i, l, r) for (int i = l; i <= r; i++)
const int inf = 0x3f3f3f3f;
const int N = 1e5 + 5;

int n;
vector<int> v(1);
int f[N];
int main() {
	cin >> n;
	v.push_back(1);
	forn(i, 1, 8) v.push_back(pow(6, i));
	forn(i, 1, 6) v.push_back(pow(9, i));

	memset(f, inf, sizeof f);
	f[0] = 0;
	forn(i, 1, v.size() - 1) {
		forn(j, v[i], n) {
			f[j] = min(f[j], f[j - v[i]] + 1);
		}
	}

	cout << f[n];
	return 0;
}
枚举
#include <bits/stdc++.h>
using namespace std;
#define forn(i, l, r) for (int i = l; i <= r; i++)

int ma(int x, int k) {
	int s = k;
	while (x > s * k) s *= k;
	return s;
}
int n, x;
int ans, res;
int main() {
	cin >> n;
	ans = n;

	forn(i, 0, n) {
		res = 0;
		x = i;
		while (x >= 9) {
			res++;
			x -= ma(x, 9);
		}
		res += x;

		x = n - i;
		while (x >= 6) {
			res++;
			x -= ma(x, 6);
		}
		res += x;

		ans = min(ans, res);
	}

	cout << ans;
	return 0;
}

D 枚举

思路 数据范围这么小?直接开暴

将每种\(i+j\)分为一组(共三组),然后枚举把每组改成同一个的代价(题目要求同一组必须颜色相同)

再枚举 3 组格子分别变成哪 3 种颜色,取最小值即可

代码
#include <bits/stdc++.h>
using namespace std;
#define forn(i, l, r) for (int i = l; i <= r; i++)
const int inf = 0x3f3f3f3f;
const int N = 5e2 + 5;

int n, m;
int c[N][N], d[N][N];
int f[N][N];
int ans = inf;
int main() {
	cin >> n >> m;
	forn(i, 1, m) forn(j, 1, m) cin >> d[i][j];
	forn(i, 1, n) forn(j, 1, n) cin >> c[i][j];

	forn(i, 1, n) {
		forn(j, 1, n) {
			forn(k, 1, m) {
				f[(i + j) % 3][k] += d[c[i][j]][k];
			}
		}
	}

	forn(i, 1, m) {
		forn(j, 1, m) {
			forn(k, 1, m) {
				if (i == j || j == k || i == k) continue;
				ans = min(ans, f[0][i] + f[1][j] + f[2][k]);
			}
		}
	}
	cout << ans;
	return 0;
}
posted @ 2023-11-04 12:17  史上最速败犬  阅读(67)  评论(0)    收藏  举报