Educational Codeforces Round 55 題解
阿新 • • 發佈:2018-11-30
題解 CF1082A 【Vasya and Book】
史上最難A題,沒有之一
從題意可以看出,翻到目標頁只有三種辦法
先從\(x\)到\(1\),再從\(1\)到\(y\)
先從\(x\)到\(n\),再從\(n\)到\(y\)
直接從\(x\)到\(y\)
三種的必要條件分別是
\((y-1)\mod d \equiv 0\)
\((n-y)\mod d \equiv 0\)
\(|x-y|\mod d \equiv 0\)
所以如果上面三種都不滿足的話就輸出\(-1\)
不然就取最小的輸出
# include <bits/stdc++.h> int main() { int T; scanf("%d", &T); while(T--) { int n, x, y, d; scanf("%d%d%d%d", &n, &x, &y, &d); int ans = 0x7f7f7f7f; if(abs(x - y) % d == 0) ans = abs(x - y) / d; if((y - 1) % d == 0) ans = std::min(ans, (x - 1) / d + bool((x - 1) % d) + (y - 1) / d); if ((n - y) % d == 0) ans = std::min(ans, (n - x) / d + bool((n - x) % d) + (n - y) / d); if(ans == 0x7f7f7f7f) { printf("-1\n"); continue; } printf("%d\n", ans); } return 0; }
題解 CF1082B 【Vova and Trophies】
\(B\)比\(A\)水qwq
這題,對每一個''\(G\)'',求它這一塊的左邊界和右邊界
然後對於每一個''\(S\)'',求一下他左邊那塊的大小,右邊那塊的大小,再判斷一下他能不能把兩塊連在一起,不能就取大的那塊,做完了
#include <bits/stdc++.h> using std::string; const int MaxN = 100010; int a[MaxN]; int l[MaxN], r[MaxN]; int main() { int n; string s; scanf("%d", &n); std::cin >> s; int len = s.length(); int sum = 0, ans = 0; for (int i = 0; i < len; i++) a[i + 1] = s[i] == 'S' ? 0 : 1, sum += a[i + 1]; if (sum == 0) return printf("0") * 0; if (sum == n) return printf("%d\n", n) * 0; for (int i = 1; i <= n; i++) { if (a[i] == 1 && a[i - 1] == 1) l[i] = l[i - 1]; else l[i] = i; } for (int i = n; i >= 1; i--) { if (a[i] == 1 && a[i + 1] == 1) r[i] = r[i + 1]; else r[i] = i; } for (int i = 1; i <= n; i++) { if (a[i] == 0) { int tmp = 0; if (a[i - 1]) tmp += r[i - 1] - l[i - 1] + 1; if (a[i + 1]) tmp += r[i + 1] - l[i + 1] + 1; if(tmp == sum) ans = std::max(ans, tmp); if (tmp < sum) ans = std::max(ans, tmp + 1); if (a[i - 1] && r[i - 1] - l[i - 1] + 1 < sum) ans = std::max(r[i - 1] - l[i - 1] + 2, ans); if (a[i + 1] && r[i + 1] - l[i + 1] + 1 < sum) ans = std::max(r[i + 1] - l[i + 1] + 2, ans); } } printf("%d\n", ans); return 0; }