AtCoder Beginner Contest 159 题解

AtCoder Beginner Contest 159

A - The Number of Even Pairs

略。

#include <bits/stdc++.h>
#define ll long long
#define rep(i, a, b) for (int i = a; i <= b; ++i)
using namespace std;
void io() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); }
ll n, m;

int main() {
	io(); cin >> n >> m;
	cout << n * (n - 1ll) / 2ll + m * (m - 1ll) / 2ll;
}

B - String Palindrome

题意:判断字符串 \(s\) 是否是回文串,并且其前一半和后一半子串均为回文串。

分析:没啥好说的,暴力判就行了。

#include <bits/stdc++.h>
#define ll long long
#define rep(i, a, b) for (int i = a; i <= b; ++i)
using namespace std;
void io() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); }
string s;

int main() {
	io(); cin >> s;
	string tmp = s;
	reverse(tmp.begin(), tmp.end());
	if (tmp != s) { cout << "No"; return 0; }
	string sa = s.substr(0, (s.length() - 1) >> 1);
	tmp = sa;
	reverse(tmp.begin(), tmp.end());
	if (tmp != sa) cout << "No";
	else cout << "Yes";
}

C - Maximum Volume

题意:已知一个长方体的表面积之和的一半为 \(L\) ,求长方体的最大体积。

分析:即已知 \(ab+bc+ca=L\) ,求 \(abc_{max}\) 。基本不等式:\(\frac{ab+bc+ca}{3}\geq\sqrt[3]{abc}\Leftrightarrow L=abc\leq (\frac{ab+bc+ca}{3})^3\)

#include <bits/stdc++.h>
#define ll long long
#define rep(i, a, b) for (int i = a; i <= b; ++i)
using namespace std;
void io() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); }
long double L;
int main() {
	io(); cin >> L;
	L /= 3.0;
	cout << fixed << setprecision(12) << (L * L * L);
}

D - Banned K

题意:有 \(N\) 只球,第 \(i\) 只球上有一个数字 \(A_i\) ,对于每一个 \(k(1\leq k \leq N)\) 询问:去掉第 \(k\) 只球后,在剩余的球中能找出几对数字相同的球。

分析:将同色球的数量存入 \(map\) 中,并计算出不去掉球的情况下选出的对数总和 \(S\) 。设某种颜色的球数量为 \(num\) ,那么拿走一只球后的总数变化为:\(S-C^2_{num}+C^2_{num-1}\)

#include <bits/stdc++.h>
#define ll long long
#define SIZE 200010
#define rep(i, a, b) for (int i = a; i <= b; ++i)
using namespace std;
void io() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); }
ll n, ans, a[SIZE];
map<ll, ll> MP;

int main() {
	io(); cin >> n;
	rep(i, 1, n) cin >> a[i], MP[a[i]]++;
	for (auto it : MP) ans += it.second * (it.second - 1ll) / 2ll;
	rep(i, 1, n) {
		ll res = MP[a[i]];
		cout << ans - res * (res - 1ll) / 2ll + (res - 1ll) * (res - 2ll) / 2ll << '\n';
	}
}

E - Dividing Chocolate

题意:给定一个 \(H\times W\)\(01\) 矩阵,要求你切割这个矩阵,使得每一块中 \(1\) 的数量不超过 \(K\) 。(一次切割只能横向或纵向切开整个矩阵,详情参考题面)

分析:注意到 \(H\leq10\) ,直接二进制枚举横向的切割方案,然后对于纵向的切割贪心判断。

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
#define ll long long
#define SIZE 2010
#define rep(i, a, b) for (int i = a; i <= b; ++i)
using namespace std;
void io() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); }
int h, w, k, a[15][SIZE], pre[15][SIZE], ans = 1e9;

int query(int xa, int ya, int xb, int yb) {
	return pre[xb][yb] - pre[xa][yb] - pre[xb][ya] + pre[xa][ya];
}

void gao(int top) {
	vector<int> vec(1, 0);
	int cnt = 1, tmp = 0, pre = 0;
	while (top) {
		if (top & 1) ++tmp, vec.emplace_back(cnt);
		top >>= 1;
		++cnt;
	}
	vec.emplace_back(h);
	
	rep(i, 1, w) {
		bool f = false;
		rep(j, 1, (vec.size() - 1)) {
			if (query(vec[j - 1], pre, vec[j], i) > k) {
				if (query(vec[j - 1], i - 1, vec[j], i) > k) return;
				f = true;
			}
		}
		if (f) { ++tmp; pre = i - 1; }
	}
	ans = min(ans, tmp);
}

int main() {
	io(); cin >> h >> w >> k;
	int top = (1 << (h - 1)) - 1;
	rep(i, 1, h) {
		string s; cin >> s;
		rep(j, 1, w) a[i][j] = s[j - 1] - '0';
	}
	rep(i, 1, h)
		rep(j, 1, w)
			pre[i][j] = a[i][j] + pre[i - 1][j] + pre[i][j - 1] - pre[i - 1][j - 1];
	for (int i = top; i >= 0; --i) gao(i);
	cout << ans;
}

F - Knapsack for All Segments

题意:给定一个长度为 \(N\) 的数组 \(A\) 和一个正整数 \(S\) ,定义 \(f(L,R)\) 为原数组中满足:\(L\leq x_1\leq x_2\leq\cdots\leq x_k \leq R\) 并且 \(x_1+x_2+\cdots + x_k=S\) 的子序列数量。求 \(\sum^N_{L=1}\sum^N_{R=L}f(L,R)\)

分析\(dp[j]\) 表示当前和为 \(j\) 的子序列数量,那么本题的方案数就可以通过 \(01\) 背包的方法转移。考虑新加入一个数字 \(a_i\) 时的转移,首先对于新加入的元素,我们只需要考虑新加入元素与先前元素构成的新子序列,即只考虑 \(f(L,R)\) 右端点变化,这一过程通过 \(01\) 背包转移方案数;然后, \(f(L,R)\) 左端点的选择是在 \([1,i]\) 范围内任意的,因此加入的 \(a_i\) 对后继的影响是: \(dp[a[i]] = (dp[a[i]] + i) \% mod\)

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
#define ll long long
#define SIZE 3010
#define rep(i, a, b) for (int i = a; i <= b; ++i)
using namespace std;
void io() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); }
const ll mod = 998244353;
ll n, s, a[SIZE], dp[SIZE], ans;

int main() {
	io(); cin >> n >> s;
	rep(i, 1, n) cin >> a[i];
	rep(i, 1, n) {
		for (int j = s; j >= a[i]; --j) {
			dp[j] += dp[j - a[i]];
			dp[j] %= mod;
		}
		if (a[i] <= s) dp[a[i]] = (dp[a[i]] + i) % mod;
		ans = (ans + dp[s]) % mod;
	}
	cout << ans;
}
posted @ 2020-03-23 20:21  st1vdy  阅读(395)  评论(0编辑  收藏  举报