题目1:
https://atcoder.jp/contests/abc339/tasks/abc339_d
代码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
// #define int long long
const int N = 66;
const int dx[] = {0, 0, -1, 1};
const int dy[] = {1, -1, 0, 0};
struct node {
int a, b, c, d;
};
int n;
string s[N];
int dp[N][N][N][N];
bool Bad(int x, int y) {
return x <= 0 || y <= 0 || x > n || y > n || s[x][y] == '#';
}
int main() {
cin >> n;
int sx1 = -1, sy1 = -1, sx2 = -1, sy2 = -1; // 两个玩家的坐标
for (int i = 1; i <= n; i++) {
cin >> s[i];
s[i] = " " + s[i]; // 方便j从1开始计数
// 确定P的坐标
for (int j = 1; j <= n; j++) {
if (s[i][j] == 'P') {
if (sx1 == -1) {
sx1 = i, sy1 = j;
} else {
sx2 = i, sy2 = j;
}
}
}
}
queue<node> q; // bfs核心--队列
q.push({sx1, sy1, sx2, sy2}); // 四个坐标一起遍历
memset(dp, -1, sizeof dp); // 表示从个点从初始状态的操作数
dp[sx1][sy1][sx2][sy2] = 0; // 初始状态操作数为0
while (!q.empty()) {
// 取队首元素
auto u = q.front();
q.pop();
int a = u.a, b = u.b, c = u.c, d = u.d;
for (int i = 0; i < 4; i++) { // 四个方向进行宽度优先搜索
// 两个点都向i方向运动
int na = a + dx[i], nb = b + dy[i];
int nc = c + dx[i], nd = d + dy[i];
// 遇到边界和障碍物
if (Bad(na, nb)) {
na = a, nb = b;
}
if (Bad(nc, nd)) {
nc = c, nd = d;
}
if (dp[na][nb][nc][nd] == -1) {
dp[na][nb][nc][nd] = dp[a][b][c][d] + 1;
q.push({na, nb, nc, nd}); // 放入队列中
}
}
}
int mn = 2e9;
for (int a = 1; a <= n; a++) {
for (int b = 1; b <= n; b++) {
if (dp[a][b][a][b] != -1) {
mn = min(mn, dp[a][b][a][b]);
}
}
}
if (mn == 2e9) {
cout << -1 << endl;
} else {
cout << mn << endl;
}
system("pause");
return 0;
}
题目2:
D-剪纸游戏_牛客小白月赛86 (nowcoder.com)
代码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
// #define int long long
#define MAX_H 1000
#define MAX_W 1000
int h, w;
char grids[MAX_H][MAX_W];
int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
typedef struct {
int y;
int x;
} Pair;
bool check(int y, int x) {
int minY = y, minX = x;
int maxY = y, maxX = x;
int cnt = 1;
// 用Pair的形式定义一个数组(实现队列)
Pair deq[MAX_H * MAX_W];
int front = 0, rear = 0;
deq[rear++] = (Pair){y, x};
grids[y][x] = '*'; // 注意这里的操作
while (front < rear) {
Pair pos = deq[front++];
for (int i = 0; i < 4; i++) {
int ty = pos.y + dirs[i][0];
int tx = pos.x + dirs[i][1];
if (ty >= 0 && ty < h && tx >= 0 && tx < w &&
grids[ty][tx] == '.') {
// 神之一手
grids[ty][tx] = '*';
deq[rear++] = (Pair){ty, tx};
cnt++;
// 计算最小点和最大点
minY = (ty < minY) ? ty : minY;
minX = (tx < minX) ? tx : minX;
maxY = (ty > maxY) ? ty : maxY;
maxX = (tx > maxX) ? tx : maxX;
}
}
}
return minY == y && minX == x &&
(maxX - minX + 1) * (maxY - minY + 1) == cnt;
}
int main() {
cin >> h >> w;
for (int i = 0; i < h; i++) {
cin >> grids[i];
}
int res = 0;
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
if (grids[i][j] == '.') {
if (check(i, j)) {
res++;
}
}
}
}
cout << res << endl;
system("pause");
return 0;
}