AtCoder Beginner Contest 338
1.A
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define int long long
signed main() {
std::ios::sync_with_stdio(false);
cin.tie(0);
string s;
cin >> s;
int n = s.size();
for (int i = 0; i < n; i++) {
if (i == 0 && s[i] >= 'a' && s[i] <= 'z') {
cout << "No" << '\n';
return 0;
}
if (i != 0 && s[i] >= 'A' && s[i] <= 'Z') {
cout << "No" << '\n';
return 0;
}
}
cout << "Yes" << '\n';
return 0;
}
2.B
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define int long long
signed main() {
std::ios::sync_with_stdio(false);
cin.tie(0);
string s;
cin >> s;
int n = s.size();
vector<int> mx(26, 0);
int maxx = 0;
for (int i = 0; i < n; i++) {
mx[s[i] - 'a']++;
maxx = max(maxx, mx[s[i] - 'a']);
}
for (int i = 0; i < 26; i++) {
if (mx[i] == maxx) {
char x = i + 'a';
cout << x << '\n';
return 0;
}
}
return 0;
}
3.C
因为N的大小只有10,所以直接考虑枚举一个人dish的数量就行。
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define int long long
const int N = 1e6 + 10;
int n;
int q[N], a[N], b[N];
signed main() {
std::ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> q[i];
}
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 1; i <= n; i++) {
cin >> b[i];
}
int mx = 1 << 30;
for (int i = 1; i <= n; i++) {
if (a[i] == 0)
continue;
else {
mx = min(mx, q[i] / a[i]);
}
}
int ans = 0;
for (int i = 0; i <= mx; i++) {
int res = 1 << 30;
for (int j = 1; j <= n; j++) {
if (b[j] == 0)
continue;
res = min(res, (q[j] - a[j] * i) / b[j]);
}
res += i;
ans = max(ans, res);
}
cout << ans << '\n';
return 0;
}
4.D
参考官方题解。
首先我们考虑a -> b是不是有顺时针和逆时针两种方式。考虑顺时针走过的桥为S,逆时针走过的桥为T。
再考虑删除每条边之后的权重。如果删除S,那么权重为T。反之一样。
最后考虑每条边被删除的权重,取一个最小值即可。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
int n, m;
cin >> n >> m;
vector<int> x(m);
for (int &i : x) {
cin >> i;
--i;
}
vector<ll> v(n + 1);
auto dist = [&](int from, int to) {
if (from <= to)
return to - from;
else
return to + n - from;
};
auto add = [&](int from, int to, int num) {
if (from <= to) {
v[from] += num;
v[to] -= num;
} else {
v[from] += num;
v[n] -= num;
v[0] += num;
v[to] -= num;
}
};
for (int i = 0; i < m - 1; i++) {
add(x[i], x[i + 1], dist(x[i + 1], x[i]));
add(x[i + 1], x[i], dist(x[i], x[i + 1]));
}
ll ans = 1LL << 60;
for (int i = 0; i < n; i++) {
v[i + 1] += v[i];
ans = min(ans, v[i]);
}
cout << ans << endl;
}
5.E
考虑两条弦有交点,必然是出现在另外一条弧的之间。
我们考虑将A作为左括号,B作为右括号。自己只能和自己匹配。这不就是一个括号匹配问题吗?
如果发生了和的匹配就证明了发生了交叉。
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
int main() {
std::ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
vector<pair<int, int>> a(2 * n);
for (int i = 1; i <= n; i++) {
int x, y;
cin >> x >> y;
x--, y--;
if (x > y)
swap(x, y);
a[x] = {0, i};
a[y] = {1, i};
}
stack<int> s;
for (int i = 0; i < 2 * n; i++) {
if (a[i].first == 0) {
s.push(a[i].second);
} else {
if (s.top() != a[i].second) {
cout << "Yes" << '\n';
return 0;
}
s.pop();
}
}
cout << "No" << '\n';
return 0;
}
6.F
N<=20,考虑状压DP。
显然是可以的。表示S状态下最后一个点为i,状态转移就是
求的是i,j之间得最短路,所以还需要一个floyd求最短路。
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
const int inf = 1 << 30;
int main() {
auto chooseMin = [&](int &a, int b) { a = min(a, b); };
std::ios::sync_with_stdio(false);
cin.tie(0);
int n, m;
cin >> n >> m;
vector<vector<int>> d(n, vector<int>(n, inf));
for (int i = 0; i < n; i++)
d[i][i] = 0;
for (int i = 0; i < m; i++) {
int u, v, w;
cin >> u >> v >> w;
--u, --v;
d[u][v] = w;
}
/**先floyd算两点之间的最短路*/
for (int k = 0; k < n; k++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (d[i][k] == inf or d[k][j] == inf)
continue;
chooseMin(d[i][j], d[i][k] + d[k][j]);
}
}
}
/**然后做状压dp*/
int maxx = 1 << n;
vector<vector<int>> dp(maxx, vector<int>(n, inf));
for (int i = 0; i < n; i++)
dp[1 << i][i] = 0;
for (int bit = 1; bit < maxx - 1; bit++) {
for (int i = 0; i < n; i++) {
if (~bit >> i & 1)
continue;
if (dp[bit][i] == inf)
continue;
for (int j = 0; j < n; j++) {
if (bit >> j & 1)
continue;
if (d[i][j] == inf)
continue;
chooseMin(dp[bit | 1 << j][j], dp[bit][i] + d[i][j]);
}
}
}
int ans = inf;
for (int i = 0; i < n; i++) {
chooseMin(ans, dp[maxx - 1][i]);
}
if (ans == inf)
cout << "No" << endl;
else
cout << ans << endl;
return 0;
}