AtCoder ABC 189 题目解析与解答
A题:简单判断三个字符是否一致
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
cin >> s;
if (s[0] == s[1] && s[1] == s[2])
cout << "Won" << endl;
else
cout << "Lost" << endl;
return 0;
}
B题:遍历计算酒精含量,寻找酒醉点
#include <iostream>
using namespace std;
typedef long long ll;
int main() {
int n, x;
cin >> n >> x;
int ans = -1;
ll total = 0;
for (int i = 0; i < n; i++) {
int v, p;
cin >> v >> p;
total += v * p;
if (ans == -1 && total > x * 100) {
ans = i + 1;
}
}
cout << ans << endl;
return 0;
}
C题:对每个位置向左右扩展,找到第一个比当前值小的位置,计算区间面积取最大值
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 1000005;
int arr[MAXN], leftB[MAXN], rightB[MAXN];
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; ++i) cin >> arr[i];
vector<pair<int, int>> st;
st.push_back({0, 0});
for (int i = 1; i <= n; ++i) {
while (st.back().first >= arr[i]) st.pop_back();
leftB[i] = st.back().second;
st.push_back({arr[i], i});
}
st.clear();
st.push_back({0, n + 1});
for (int i = n; i >= 1; --i) {
while (st.back().first >= arr[i]) st.pop_back();
rightB[i] = st.back().second;
st.push_back({arr[i], i});
}
ll best = 0;
for (int i = 1; i <= n; ++i) {
best = max(best, (ll)arr[i] * (rightB[i] - leftB[i] - 1));
}
cout << best << endl;
return 0;
}
D题:状态DP,记录当前结果为真和假的方案数
#include <iostream>
#include <string>
using namespace std;
typedef long long ll;
const int MAXN = 1000005;
ll trueCnt[MAXN], falseCnt[MAXN];
int main() {
int n;
cin >> n;
trueCnt[0] = falseCnt[0] = 1;
for (int i = 1; i <= n; ++i) {
string op;
cin >> op;
if (op == "AND") {
trueCnt[i] = 2 * trueCnt[i - 1] + falseCnt[i - 1];
falseCnt[i] = falseCnt[i - 1];
} else {
trueCnt[i] = trueCnt[i - 1];
falseCnt[i] = trueCnt[i - 1] + 2 * falseCnt[i - 1];
}
}
cout << trueCnt[n] << endl;
return 0;
}
E题:维护变换函数,快速回答多个点在不同操作后的坐标
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 1000005;
ll xs[MAXN], ys[MAXN], op1[MAXN], op2[MAXN];
pair<ll, ll> result[MAXN];
ll eval(ll idx, pair<ll, pair<ll, ll>> func) {
ll val = (func.first == 0) ? xs[idx] : ys[idx];
return val * func.second.first + func.second.second;
}
int main() {
ll n, m, q;
cin >> n;
for (ll i = 1; i <= n; ++i) cin >> xs[i] >> ys[i];
cin >> m;
for (ll i = 1; i <= m; ++i) {
cin >> op1[i];
if (op1[i] >= 3) cin >> op2[i];
}
cin >> q;
vector<pair<ll, pair<ll, ll>>> queries;
for (ll i = 0; i < q; ++i) {
ll a, b;
cin >> a >> b;
queries.push_back({a, {b, i}});
}
sort(queries.begin(), queries.end());
pair<ll, pair<ll, ll>> fx = {0, {1, 0}};
pair<ll, pair<ll, ll>> fy = {1, {1, 0}};
ll idx = 0;
for (ll i = 0; i <= m; ++i) {
if (op1[i] == 1) {
swap(fx, fy);
fy.second.first *= -1;
fy.second.second *= -1;
} else if (op1[i] == 2) {
swap(fx, fy);
fx.second.first *= -1;
fx.second.second *= -1;
} else if (op1[i] == 3) {
fx.second.first *= -1;
fx.second.second = 2 * op2[i] - fx.second.second;
} else if (op1[i] == 4) {
fy.second.first *= -1;
fy.second.second = 2 * op2[i] - fy.second.second;
}
while (idx < q && queries[idx].first == i) {
ll id = queries[idx].second.second;
ll pos = queries[idx].second.first;
result[id].first = eval(pos, fx);
result[id].second = eval(pos, fy);
idx++;
}
}
for (ll i = 0; i < q; ++i) {
cout << result[i].first << ' ' << result[i].second << endl;
}
return 0;
}
F题:使用期望递推,处理特殊位置回退到起点的情况
#include <iostream>
#include <set>
#include <cmath>
#include <cstdio>
using namespace std;
const int MAXN = 1000005;
pair<double, double> dp[MAXN];
int main() {
int n, m, k;
cin >> n >> m >> k;
set<int> trap;
for (int i = 0; i < k; ++i) {
int x;
cin >> x;
trap.insert(x);
}
dp[n] = {0, 0};
pair<double, double> sum = {0, 0};
for (int i = n - 1; i >= 0; --i) {
sum.first += dp[i + 1].first;
sum.second += dp[i + 1].second;
sum.first -= dp[min(n, i + m + 1)].first;
sum.second -= dp[min(n, i + m + 1)].second;
if (trap.count(i)) {
dp[i] = {1, 0};
} else {
dp[i].first = sum.first / m;
dp[i].second = sum.second / m + 1;
}
}
if (fabs(dp[0].first - 1.0) < 1e-12) {
cout << -1 << endl;
} else {
printf("%.4f\n", dp[0].second / (1 - dp[0].first));
}
return 0;
}