// 正十字,a,b为之前的位置,x,y为当前的位置,now为当前待匹配的字母位,cnt为转弯次数 voiddfs1(int a, int b, int x, int y, int now, int cnt) { if (g[x][y] != s[now]) return;
if (now == s.size() - 1) { if (cnt <= 1) res++; return; }
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
for (int k = 0; k < 4; k ++) { int i = x + dx[k], j = y + dy[k]; if (x < 0 || x >= m || y < 0 || y >= n) continue;
// 判断是否转弯(now不是起点 且 pre和next行列均不相等) if (a != -1 && b != -1 && a != i && b != j) dfs1(x, y, i, j, now + 1, cnt + 1); elsedfs1(x, y, i, j, now + 1, cnt); } }
// 斜十字 voiddfs2(int a, int b, int x, int y, int now, int cnt) { if (g[x][y] != s[now]) return;
if (now == s.size() - 1) { if (cnt <= 1) res++; return; }
int dx[] = {-1, -1, 1, 1}, dy[] = {-1, 1, 1, -1};
for (int k = 0; k < 4; k ++) { int i = x + dx[k], j = y + dy[k]; if (x < 0 || x >= m || y < 0 || y >= n) continue;
// 判断是否转弯(now不是起点 且 不在同一对角线) if (a != -1 && b != -1 && (a == i || b == j)) dfs2(x, y, i, j, now + 1, cnt + 1); elsedfs2(x, y, i, j, now + 1, cnt); } }
intmain() { cin >> s; cin >> m >> n;
for (int i = 0; i < m; i ++) for (int j = 0; j < n; j ++) cin >> g[i][j];
for (int i = 0; i < m; i ++) for (int j = 0; j < n; j ++) dfs1(-1, -1, i, j, 0, 0);
for (int i = 0; i < m; i ++) for (int j = 0; j < n; j ++) dfs2(-1, -1, i, j, 0, 0);
int n, k; string s = "DKER EPH VOS GOLNJ ER RKH HNG OI RKH UOPMGB CPH VOS FSQVB DLMM VOS QETH SQB"; string t1 = "DKER EPH VOS GOLNJ UKLMH QHNGLNJ A"; string t2 = "AB CPH VOS FSQVB DLMM VOS QHNG A"; string t3 = "AB";
// 记录每一层构造出来的字符串 Si 的长度 len,当前递归的层数 i (i>=1),对于当前层数需要查询的字符的下标 pos voiddfs(vector<int>& len, int i, int pos, bool& ok){ // 已经搜到答案了就不断返回 if (ok) { return; }
ll dfs(int a, int b, int c){ if (a <= 0 || b <= 0 || c <= 0) return1; elseif (a > 20 || b > 20 || c > 20) returndfs(20, 20, 20); elseif (a < b && b < c) returndfs(a, b, c - 1) + dfs(a, b - 1, c - 1) - dfs(a, b - 1, c); elsereturndfs(a - 1, b, c) + dfs(a - 1, b - 1, c) + dfs(a - 1, b, c - 1) - dfs(a - 1, b - 1, c - 1); }
voidsolve(){ int a, b, c; cin >> a >> b >> c; while (a != -1 && b != -1 && c != -1) { printf("w(%d, %d, %d) = %lld\n", a, b, c, dfs(a, b, c)); cin >> a >> b >> c; } }
signedmain(){ ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int T = 1; // cin >> T; while (T--) solve(); return0; }
ll dfs(ll a, ll b, ll c){ // 上下界 if (a <= 0 || b <= 0 || c <= 0) return1; elseif (a > 20 || b > 20 || c > 20) returndfs(20, 20, 20);
if (f[a][b][c]) { // 已经记忆化过了,直接返回当前状态的解 return f[a][b][c]; } else { // 没有记忆化过,就递归计算并且记忆化 if (a < b && b < c) return f[a][b][c] = dfs(a, b, c - 1) + dfs(a, b - 1, c - 1) - dfs(a, b - 1, c); elsereturn f[a][b][c] = dfs(a - 1, b, c) + dfs(a - 1, b - 1, c) + dfs(a - 1, b, c - 1) - dfs(a - 1, b - 1, c - 1); } }
voidsolve(){ ll a, b, c; cin >> a >> b >> c; while (!(a == -1 && b == -1 && c == -1)) { printf("w(%lld, %lld, %lld) = %lld\n", a, b, c, dfs(a, b, c)); cin >> a >> b >> c; } }
signedmain(){ ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int T = 1; // cin >> T; while (T--) solve(); return0; }
while (q.size()) { auto& now = q.front(); q.pop();
for (int i = 0; i < 4; i++) { int x = dx[i] + now.first, y = dy[i] + now.second; if (x >= 1 && x <= n && y >= 1 && y <= n && !vis[x][y] && g[x][y] != g[now.first][now.second]) { q.push({x, y}); a.push_back({x, y}); vis[x][y] = true; cnt++; } } }
for (auto& loc: a) { res[loc.first][loc.second] = cnt; } }
voidsolve(){ cin >> n >> m; for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) cin >> g[i][j];
for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (!vis[i][j]) bfs(i, j);
while (m--) { int a, b; cin >> a >> b; if (vis[a][b]) { cout << res[a][b] << "\n"; } else { cout << 1 << "\n"; } } }
intmain(){ ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int T = 1; // cin >> T; while (T--) solve(); return0; }
int n, m, res[N][N]; char g[N][N]; bool vis[N][N];
// 当前点的坐标 (u, v),当前连通块的元素个数cnt,当前连通块的元素存到 a 数组 voiddfs(int u, int v, int& cnt, vector<pair<int, int>>& a){ cnt++; a.push_back({u, v}); vis[u][v] = true;
int dx[4] = {0, 0, 1, -1}, dy[4] = {1, -1, 0, 0};
for (int k = 0; k < 4; k++) { int x = u + dx[k], y = v + dy[k]; if (x >= 1 && x <= n && y >= 1 && y <= n && !vis[x][y] && g[x][y] != g[u][v]) { dfs(x, y, cnt, a); } } }
voidsolve(){ cin >> n >> m; for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) cin >> g[i][j];
for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (!vis[i][j]) { int cnt = 0; vector<pair<int, int>> a; dfs(i, j, cnt, a); for (auto& loc: a) { res[loc.first][loc.second] = cnt; } }
while (m--) { int a, b; cin >> a >> b; if (vis[a][b]) { cout << res[a][b] << "\n"; } else { cout << 1 << "\n"; } } }
intmain(){ ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int T = 1; // cin >> T; while (T--) solve(); return0; }
#include<bits/stdc++.h> #define int long long usingnamespace std;
constint N = 25;
int a[N], res;
voidfun(int n){ int MIN = 20 * 60; for (int i = 0; i <= (1 << n); i++) { int l = 0, r = 0; for (int j = 0; j < n; j++) { if (i & (1 << j)) r += a[j]; else l += a[j]; } MIN = min(MIN, max(l, r)); } res += MIN; }
voidsolve(){ int x[4] {}; for (int i = 0; i < 4; i++) cin >> x[i];
for (int i = 0; i < 4; i++) { for (int j = 0; j < x[i]; j++) cin >> a[j]; fun(x[i]); }
cout << res << "\n"; }
signedmain(){ ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int T = 1; // cin >> T; while (T--) solve(); return0; }
#include<bits/stdc++.h> #define int long long usingnamespace std;
constint N = 10;
int n, m, k; int aa, bb, cc, dd; int g[N][N], vis[N][N]; int res;
int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, 1, -1};
voiddfs(int x, int y){ if (x == cc && y == dd) { res++; return; }
for (int k = 0; k < 4; k++) { int xx = x + dx[k], yy = y + dy[k]; if (xx > 0 && xx <= n && yy > 0 && yy <= m && !g[xx][yy] && !vis[xx][yy]) { vis[x][y] = true; dfs(xx, yy); vis[x][y] = false; } } }
voidsolve(){ cin >> n >> m >> k; cin >> aa >> bb >> cc >> dd;
while (k--) { int x, y; cin >> x >> y; g[x][y] = 1; }
dfs(aa, bb);
cout << res << "\n"; }
signedmain(){ ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int T = 1; // cin >> T; while (T--) solve(); return0; }
#include<bits/stdc++.h> #define int long long usingnamespace std;
constint N = 110;
int n, m; char g[N][N]; bool vis[N][N]; int res, dx[] = {1, -1, 0, 0, 1, 1, -1, -1}, dy[] = {0, 0, 1, -1, 1, -1, 1, -1};
voidbfs(int i, int j){ queue<pair<int, int>> q;
q.push({i, j}); vis[i][j] = true;
while (q.size()) { auto h = q.front(); q.pop();
int x = h.first, y = h.second; for (int k = 0; k < 8; k++) { int xx = x + dx[k], yy = y + dy[k]; if (!vis[xx][yy] && g[xx][yy] == 'W') { q.push({xx, yy}); vis[xx][yy] = true; } } } }
voidsolve(){ cin >> n >> m; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) cin >> g[i][j];
for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) if (!vis[i][j] && g[i][j] == 'W') bfs(i, j), res++;
cout << res << "\n"; }
signedmain(){ ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int T = 1; // cin >> T; while (T--) solve(); return0; }
#include<bits/stdc++.h> #define int long long usingnamespace std;
constint N = 35;
int n, g[N][N]; int dx[] = {0, 0, 1, -1}, dy[] = {1, -1, 0, 0}; bool vis[N][N];
voiddfs(int i, int j){ if (i < 1 || i > n || j < 1 || j > n || g[i][j] == 1 || vis[i][j]) return;
vis[i][j] = true;
for (int k = 0; k < 4; k++) { int x = i + dx[k], y = j + dy[k]; dfs(x, y); } }
voidsolve(){ cin >> n;
for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) cin >> g[i][j];
for (int i = 1; i <= n; i++) if (g[1][i] == 0 && !vis[1][i]) dfs(1, i); for (int i = 1; i <= n; i++) if (g[i][n] == 0 && !vis[i][n]) dfs(i, n); for (int i = 1; i <= n; i++) if (g[n][i] == 0 && !vis[n][i]) dfs(n, i); for (int i = 1; i <= n; i++) if (g[i][1] == 0 && !vis[i][1]) dfs(i, 1);
for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (vis[i][j]) cout << 0 << " \n"[j == n]; elseif (g[i][j] == 0) cout << 2 << " \n"[j == n]; else cout << g[i][j] << " \n"[j == n]; }
signedmain(){ ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int T = 1; // cin >> T; while (T--) solve(); return0; }
classSolution { public: vector<int> countPairsOfConnectableServers(vector<vector<int>>& edges, int signalSpeed){ int n = edges.size() + 1;
structnode { int to, w; }; vector<vector<node>> g(n, vector<node>()); for (auto e: edges) { int u = e[0], v = e[1], w = e[2]; g[u].push_back({v, w}); g[v].push_back({u, w}); }
function<int(int, int, int)> dfs = [&](int fa, int now, int d) { int res = d % signalSpeed == 0; for (auto ch: g[now]) { if (ch.to != fa) { res += dfs(now, ch.to, d + ch.w); } } return res; };
vector<int> res(n); for (int i = 0; i < n; i++) { int sum = 0; for (auto ch: g[i]) { int cnt = dfs(i, ch.to, ch.w); res[i] += cnt * sum; sum += cnt; } }
思路:可以将这道题抽象为求解「将 a 个大于 1 位置的数分配到 b 个 0 位置」的方案中的最小代价问题。容易联想到全排列选数的母问题:数字的位数对应这里的 b 个 0 位置,每个位置可以填的数对应这里的用哪个 a 来填。区别在于:0 的位置顺序不是固定的,用哪个 a 来填的顺序也不是固定的。这与全排列数中:被填的位置顺序是固定的,用哪个数来填不是固定的,有所区别。因此我们可以全排列枚举每一个位置,在此基础之上再全排列枚举每一个位置上可选的 a 进行填充。可以理解为全排列的嵌套。那么最终递归树的深度就是 0 的个数,递归时再用一个参数记录每一个选数分支对应的代价即可。
classSolution { public: intminimumMoves(vector<vector<int>>& g){ vector<pair<int, int>> z, a; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (!g[i][j]) { z.push_back({i, j}); } else { while (g[i][j] > 1) { a.push_back({i, j}); g[i][j]--; } } } }
int res = INT_MAX; do { int t = 0; for (int i = 0; i < z.size(); i++) { t += abs(a[i].first - z[i].first) + abs(a[i].second - z[i].second); } res = min(res, t); } while (next_permutation(a.begin(), a.end()));
classSolution: defminimumMoves(self, g: List[List[int]]) -> int: a, z = [], [] for i inrange(3): for j inrange(3): ifnot g[i][j]: z.append((i, j)) elif g[i][j] > 1: a.append((i, j))
res = 1000 n = len(z) vis = [False] * n
defdfs(dep: int, t: int) -> None: nonlocal res if dep == n: res = min(res, t) return for i inrange(n): if vis[i]: continue vis[i] = True for x, y in a: if g[x][y] <= 1: continue g[x][y] -= 1 dfs(dep + 1, t + abs(z[i][0] - x) + abs(z[i][1] - y)) g[x][y] += 1 vis[i] = False
classSolution: defminimumMoves(self, g: List[List[int]]) -> int: from itertools import permutations a, z = [], [] for i inrange(3): for j inrange(3): ifnot g[i][j]: z.append((i, j)) while g[i][j] > 1: a.append((i, j)) g[i][j] -= 1
res, n = 1000, len(a) for p in permutations(a): t = 0 for i inrange(n): t += abs(p[i][0] - z[i][0]) + abs(p[i][1] - z[i][1]) res = min(res, t)