「賽後總結」AtCoder Beginner Contest 184
題意 & 題解
A.Determinant
題意:
給你 \(a,b,c,d\),計算 \(ad-ba\)。
題解:
簽到題。
B.Quizzes
題意:
已有分數 \(X\),讀到 x
並且 \(X>0\) 則 \(X-1\),讀到 o
則 \(X + 1\)。
題解:
簽到題。
C.Super Ryuma
題意:
給一個起點一個終點,可以往當前點所在在對角線或者曼哈頓距離為 \(3\) 以內的整點上跳,問最少幾步到達終點。
題解:
最多跳三次。
如果起點終點重合,共零次。如果終點在起點能跳到的電上,共一次。兩個點的對角線一定有個交點,如果是橫座標整數可以先跳到交點再往終點跳,還有其他跳的方式,不細說了,共兩次。如果不是整數可以先跳到終點的對角線附近,再跳到對角線上,再跳一次,共三次。
D.increment of coins
題意:
初始時有 \(a\) 個金幣,\(b\) 個銀幣,\(c\) 個銅幣,每次可以隨機取出一個 \(x\) 並放入兩個相同的 \(x\)。當出現 \(100\) 個相同的幣時停止,問操作次數的期望。
題解:
\(f_{i,j,k}\) 表示 \(i\) 個金幣,\(j\) 個銀幣,\(k\) 個銅幣到結束的操作次數的期望。
下一步可以到 \(f_{i+1,j,k}\)、\(f_{i,j + 1,k}\)、\(f_{i,j,k + 1}\) 三種狀態。
\(f_{i,j,k} = (f_{i+1,j,k}+1)\times\frac{i}{i+j+kj} + (f_{i,j+1,k}+1)\times\frac{j}{i+j+kj}+(f_{i,j,k+1}+1)\times\frac{k}{i+j+kj}\)
個人感覺記憶化搜尋比較好寫。
E.Third Avenue
題意:
一個地圖,可以向上下左右走,相同的小寫字母可以互相傳送,每一個操作都要一秒時間,問從起點到終點要耗費的最短時間。
題解:
字母只會在第一次遇到時進行傳送,所以直接寬搜。
F.Programming Contest
題意:
給定 \(n\) 個數以及一個 \(t\),你要找到若干數的和使它最大並且不超過 \(t\)。
題解:
\(n \le 40\),用折半搜尋搜出前 \(20\) 個數和後 \(20\) 個數的選法之後用二分進行配對。
Code
A.Determinant
#include <cstdio> #include <iostream> int main() { int a, b, c, d; scanf("%d %d %d %d", &a, &b, &c, &d); std::cout << a * d - b * c << '\n'; return 0; }
B.Quizzes
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
int n, x;
std::string s;
int main() {
std::cin >> n >> x >> s;
for (int i = 0; i < n; ++i) {
if (s[i] == 'o') ++x;
if (s[i] == 'x' && x) --x;
}
std::cout << x << '\n';
return 0;
}
C.Super Ryuma
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
long long r1, c1, r2, c2;
int main() {
std::cin >> r1 >> c1 >> r2 >> c2;
if (r1 == r2 && c1 == c2) return puts("0"), 0;
if (r1 + c1 == r2 + c2 || r1 - c1 == r2 - c2 || abs(r1 - r2) + abs(c1 - c2) <= 3) return puts("1"), 0;
bool flag = false;
if ((r2 + c2 + r1 - c1) % 2 == 0 || (r1 + c1 + r2 - c2) % 2 == 0) return puts("2"), 0;
for (int i = r1 - 3; i <= r1 + 3; ++i) {
for (int j = c1 - 3; j <= c1 + 3; ++j) {
if (abs(r1 - i) + abs(c1 - j) > 3) continue;
if (i + j == r2 + c2 || i - j == r2 - c2 || abs(i - r2) + abs(j - c2) <= 3) flag = true;
}
}
for (int i = r2 - 3; i <= r2 + 3; ++i) {
for (int j = c2 - 3; j <= c2 + 3; ++j) {
if (abs(r2 - i) + abs(c2 - j) > 3) continue;
if (i + j == r1 + c1 || i - j == r1 - c1 || abs(i - r1) + abs(j - c1) <= 3) flag = true;
}
}
if (flag) return puts("2"), 0;
return puts("3"), 0;
}
D.increment of coins
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 101
int a, b, c;
double f[M][M][M];
double dfs(int x, int y, int z) {
if (x >= 100 || y >= 100 || z >= 100) return 0;
if (f[x][y][z] != -1) return f[x][y][z];
f[x][y][z] = (dfs(x + 1, y, z) + 1) * ((x * 1.0) / (1.0 * (x + y + z)));
f[x][y][z] += (dfs(x, y + 1, z) + 1) * ((y * 1.0) / (1.0 * (x + y + z)));
f[x][y][z] += (dfs(x, y, z + 1) + 1) * ((z * 1.0) / (1.0 * (x + y + z)));
return f[x][y][z];
}
int main() {
for (int i = 0; i <= 100; ++i) {
for (int j = 0; j <= 100; ++j) {
for (int k = 0; k <= 100; ++k) {
f[i][j][k] = -1;
}
}
}
std::cin >> a >> b >> c;
printf("%.9lf\n", dfs(a, b, c));
return 0;
}
E.Third Avenue
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#define M 2001
typedef std::pair<int, int> pii;
std::queue<pii> q;
std::vector<pii> V[27];
std::string map[M];
int n, m, a, b, d[M][M];
bool vis[M][M], used[M], f;
int dx[5] = {0, 1, -1, 0, 0};
int dy[5] = {0, 0, 0, 1, -1};
void bfs(int sx, int sy) {
q.push(std::make_pair(sx, sy));
d[sx][sy] = 0, vis[sx][sy] = true;
while (!q.empty()) {
int x = q.front().first, y = q.front().second; q.pop();
if (map[x][y] == 'G') { f = 1, printf("%d\n", d[x][y]); return; }
for (int i = 1; i <= 4; ++i) {
int x_ = x + dx[i], y_ = y + dy[i];
if (x_ <= 0 || x_ > n || y_ < 0 || y_ >= m) continue;
if (map[x][y] == '#' || vis[x_][y_]) continue;
vis[x_][y_] = true, d[x_][y_] = d[x][y] + 1;
q.push(std::make_pair(x_, y_));
}
if (map[x][y] < 'a' || map[x][y] > 'z' || used[map[x][y] - 'a']) continue;
used[map[x][y] - 'a'] = true;
for (int i = 0; i < V[map[x][y] - 'a'].size(); ++i) {
int x_ = V[map[x][y] - 'a'][i].first, y_ = V[map[x][y] - 'a'][i].second;
if (vis[x_][y_]) continue;
vis[x_][y_] = true, d[x_][y_] = d[x][y] + 1;
q.push(std::make_pair(x_, y_));
}
}
}
int main() {
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; ++i) std::cin >> map[i];
for (int i = 1; i <= n; ++i) {
for (int j = 0; j < m; ++j) {
if (map[i][j] == 'S') a = i, b = j;
if (map[i][j] >= 'a' && map[i][j] <= 'z') {
V[map[i][j] - 'a'].push_back(std::make_pair(i, j));
}
}
}
bfs(a, b);
if (!f) puts("-1");
return 0;
}
F.Programming Contest
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 21
int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }
int n, m, t, c1, c2, a[M], b[M];
int ans, ans1[1 << M], ans2[1 << M];
void dfs1(int step, int now) {
if (now > t) return;
if (step > n) { ans1[++c1] = now; return; }
for (int i = 0; i <= 1; ++i) {
if (i == 1) dfs1(step + 1, now + a[step]);
if (i == 0) dfs1(step + 1, now);
}
}
void dfs2(int step, int now) {
if (now > t) return;
if (step > m) { ans2[++c2] = now; return; }
for (int i = 0; i <= 1; ++i) {
if (i == 1) dfs2(step + 1, now + b[step]);
if (i == 0) dfs2(step + 1, now);
}
}
int main() {
scanf("%d %d", &n, &t);
m = n - 20, n = min(n, 20);
for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
for (int i = 1; i <= m; ++i) scanf("%d", &b[i]);
dfs1(1, 0);
if (m > 0) dfs2(1, 0);
std::sort(ans1, ans1 + c1 + 1);
std::sort(ans2, ans2 + c2 + 1);
for (int i = 0; i <= c1; ++i) {
int temp = t - ans1[i];
int pos = std::lower_bound(ans2, ans2 + c2 + 1, temp) - ans2;
if (pos == c2 + 1 || ans2[pos] > temp) --pos;
ans = max(ans, ans1[i] + ans2[pos]);
}
std::cout << ans << '\n';
return 0;
}