Educational Codeforces Round 99 (Rated for Div. 2)
A. Strange Functions
读懂题即可(或者快速看一下样例解释),直接输出字符串长度即可。
void solve() {string s;cin >> s;cout << s.length() << endl;}
B. Jumps
这是一个数轴移动问题,按题意推导一下就好
void solve() {int x; cin >> x;int cnt = 0;while (cnt * (cnt + 1) < (x << 1)) cnt++;if (cnt * (cnt + 1) / 2 == x + 1) cnt++;cout << cnt << endl;}
C. Ping-pong
题意是Alice 和 Bob 开始玩击球游戏,但他们只有 x 和 y 个体力,每次发球和击回都要消耗一点体力,问怎么应对才能使两方的赢数最大
根据样例解释,其实对Bob而言只要我不回第一球,那么后面都会是Bob赢。那么就很简单了,次数为
void solve() {int x, y;cin >> x >> y;cout << x - 1 << " " << y << endl;}
D. Sequence and Swaps
这道题一开始想简单了,正确思路是先判断是否已经排序好了,如果是的话直接输出0,不然把x插入每个位置进行尝试,即计算逆序,每次都进行最小值判断。
AC代码 ↓
void solve() {int n, x;cin >> n >> x;vector<int> a(n);for (int i = 0; i < n; ++i)cin >> a[i];int ans = n + 1;if (is_sorted(a.begin(), a.end())){//STL函数,判断是否有序cout << 0 << endl;return;}for (int i = 0; i < n; ++i) {vector<int> b(a);b[i] = x;sort(b.begin(), b.end());int cur = x, cnt = 0;bool f = true;for (int j = 0; j < n; ++j) {if (a[j] != b[j]) {++cnt;if (cur == b[j] && b[j] < a[j])cur = a[j];elsef = false;}}if (f)ans = min(ans, cnt);}if (ans > n)ans = -1;cout << ans << "\n";}
E. Four Points

直接去写的话感觉很麻烦,这里思路借鉴了rank2的大神的代码:转化为复数处理。
对标样例模拟就清楚了。
void solve() {ll ans = 1e18;pair<int, int> p[4];for (int i = 0; i < 4; ++i)cin >> p[i].first >> p[i].second;sort(p, p + 4);do {vector<int> cand{0};for (int i = 0; i < 2; ++i)for (int j = 0; j < 2; ++j) {cand.push_back(p[2 + j].first - p[i].first);cand.push_back(p[2 * j + 1].second - p[2 * i].second);}for (auto d : cand) {if (d < 0)continue;ll res = 0;int x[4], y[4];for (int i = 0; i < 4; ++i)tie(x[i], y[i]) = p[i]; //转化为复数处理x[2] -= d, x[3] -= d;y[1] -= d, y[3] -= d;sort(x, x + 4), sort(y, y + 4);for (int i = 0; i < 4; ++i) {res += abs(x[i] - x[1]);res += abs(y[i] - y[1]);}ans = min(res, ans);}} while (next_permutation(p, p + 4));cout << ans << endl;}
F. String and Operations
贴一下dalao代码作为学习
void update(std::string& a, const std::string& b) {if (a.empty() || a > b)a = b;}void solve() {int n, k;std::cin >> n >> k;std::string a, b;std::cin >> a;b = a;for (int i = 0; i < n; ++i) {if (b[i] == 'a' + k - 1)b[i] = 'a';else if (b[i] != 'a')--b[i];}std::string dp[2][2];dp[0][0] = a;int cur = 0;for (int i = 0; i < n; ++i) {cur ^= 1;dp[cur][0] = dp[cur][1] = "";if (!dp[!cur][0].empty()) {auto& s = dp[!cur][0];update(dp[cur][0], s);if (i > 0) {std::swap(s[i], s[i - 1]);update(dp[cur][0], s);std::swap(s[i], s[i - 1]);}if (i + 1 < n) {std::swap(s[i], s[i + 1]);update(dp[cur][1], s);std::swap(s[i], s[i + 1]);}s[i] = b[i];update(dp[cur][0], s);}if (!dp[!cur][1].empty()) {auto& s = dp[!cur][1];update(dp[cur][0], s);if (i > 1) {std::swap(s[i - 1], s[i - 2]);update(dp[cur][0], s);std::swap(s[i - 1], s[i - 2]);}s[i - 1] = b[i];update(dp[cur][0], s);}}std::cout << dp[cur][0] << "\n";}
G. Forbidden Value
最后一道题似乎是线段树 + DP ? 看完题没啥思路。。。(老菜鸡了)
