boolvalid(int i, int j, int x, int dir){ int left = j; if (dl[dir] > 0) left = j + x * dl[dir] - 1; elseif (dl[dir] < 0) left = j + x * dl[dir] + 1;
int right = j; if (dr[dir] > 0) right = j + x * dr[dir] - 1; elseif (dr[dir] < 0) right = j + x * dr[dir] + 1;
int up = i; if (du[dir] > 0) up = i + x * du[dir] - 1; elseif (du[dir] < 0) up = i + x * du[dir] + 1;
int down = i; if (dd[dir] > 0) down = i + x * dd[dir] - 1; elseif (dd[dir] < 0) down = i + x * dd[dir] + 1;
if (up < 1 || right > c || left < 1 || down > r) returnfalse; int h = abs(sumR[i][right] - sumR[i][left - 1]); int v = abs(sumC[j][down] - sumC[j][up - 1]); return ((h == x) && (v == 2 * x)) || ((h == 2 * x) && (v == x)); }
LL calc(int dir){ LL ans = 0; for (int i = 1; i <= r; i++) { for (int j = 1; j <= c; j++) { int l = 0, right = max(r, c); while (l < right) { int mid = (l + right + 1) >> 1; if (valid(i, j, mid, dir)) { l = mid; } else { right = mid - 1; } } if (l < 2) continue; ans += l - 1; } } return ans; }
LL solve(){ LL ans = 0; for (int i = 0; i < 8; i++) { ans += calc(i); } return ans; }
intmain(){ cin >> t; for (int i = 1; i <= t; i++) { cin >> r >> c; for (int i = 1; i <= r; i++) { for (int j = 1; j <= c; j++) { cin >> g[i][j]; sumR[i][j] = sumR[i][j - 1] + g[i][j]; sumC[j][i] = sumC[j][i - 1] + g[i][j]; } } printf("Case #%d: %lld\n", i, solve()); } return0; }
int t, g[N][N], r, c, v[N][N]; int maxV = 0, maxI, maxJ; int dx[] = {0, 0, 1, -1}; int dy[] = {1, -1, 0, 0};
boolvalid(int x, int y){ return x >= 0 && x < r && y >= 0 && y < c; }
structP { int x, y, val; booloperator<(P b) const { return val < b.val; } };
priority_queue<P> q; LL solve(){ if (maxV == 0) return0; LL ans = 0; for (int i = 0; i < r; i++) { for (int j = 0; j < c; j++) { q.push({i, j, g[i][j]}); } } int cnt = 0; while (q.size()) { auto now = q.top(); q.pop(); if (v[now.x][now.y]) continue; v[now.x][now.y] = 1; if (++cnt == r * c) return ans; for (int k = 0; k < 4; k++) { int x = now.x + dx[k]; int y = now.y + dy[k]; if (!valid(x, y)) continue; int goal = g[now.x][now.y] - 1; if (g[x][y] < goal) { ans += goal - g[x][y]; g[x][y] = goal; } q.push({x, y, g[x][y]}); } } return ans; }
intmain(){ cin >> t; for (int i = 1; i <= t; i++) { cin >> r >> c; maxV = 0; memset(v, 0, sizeof v); q = priority_queue<P>(); for (int i = 0; i < r; i++) { for (int j = 0; j < c; j++) { cin >> g[i][j]; if (g[i][j] > maxV) { maxI = i, maxJ = j; maxV = g[i][j]; } } } printf("Case #%d: %lld\n", i, solve()); } return0; }
intsolve(){ int ans = 0; sort(edge, edge + m); for (int i = 0; i < m; i++) { int x = get(edge[i].x); int y = get(edge[i].y); if (x == y) continue; fa[x] = y; ans += edge[i].z; } // 最大生成树是留下的边,删除的边就是付出的代价 return sum - ans; }
intmain(){ cin >> t; for (int i = 1; i <= t; i++) { m = sum = 0; cin >> n; // 并查集初始化 for (int i = 0; i <= 2 * n; i++) fa[i] = i;
for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cin >> a[i][j]; } } for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cin >> b[i][j]; if (a[i][j] == -1) { // 行节点从 0 开始编号,列节点从 n 开始编号 // 边权为恢复代价 int x = i, y = j + n; sum += b[i][j]; edge[m++] = {x, y, b[i][j]}; } } } // 这道题中,r, c 是什么其实没有关系,KickStart 喜欢搞这种迷惑人 for (int i = 0; i < n; i++) { cin >> r[i]; } for (int i = 0; i < n; i++) { cin >> c[i]; } printf("Case #%d: %d\n", i, solve()); } return0; }