题解:B4186 [中山市赛 2024/科大国创杯小学组 2023] 六形棋/海克斯
Background
算法:广度优先搜索。
几乎是广搜模板题,没有任何别的什么处理。
至于题目的六边形设定,直接把六个边对应的邻点当做可以扩展的位置,然后当做矩形做即可。
Solution
-
先存图,然后依次遍历第一行、第一列,若找到对应人的棋子,就以这个起点开始广搜。
-
广搜扩展时,若当前格子为自己的棋子,那么可以更新,入队;否则当做障碍,不可更新,跳过。
-
对于每个从队列里面取出的点,直接看是否到了对应的边界,若到了直接返回结果即可,因为题中说了结果唯一。
Code
细节可以看代码。
由于范围不大,直接写临时变量,省的忘记清空。
扩展中的坐标加减情况写常量数组。
#include<bits/stdc++.h>
#define N 105
using namespace std;
class Quick_IO
{
public:
template<typename T>
void read(T &r)
{
T x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9')
{
if (ch == '-') f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
r = x * f;
}
template<typename T, typename... Args>
void read(T &tmp, Args &... tmps)
{
read(tmp);
read(tmps...);
}
} io;
const int mx[7] = {0, 0, 0, 1, 1, -1, -1};
const int my[7] = {0, 1, -1, 0, -1, 0, 1};
int G[N][N];
int T, n;
struct node
{
int x, y;
};
bool INRANGE(int x, int y)
{
return (x >= 1 && y >= 1 && x <= n && y <= n);
}
bool BFS(int sx, int sy, bool is_Jimmy) //起始位置,是否是吉米
{
bool vis[N][N] = {}; //由于范围不大,直接写临时变量,省的清空
queue<node> Q;
Q.push({sx, sy});
vis[sx][sy] = 1; //标记走过
while (Q.size()) //BFS
{
int ux = Q.front().x, uy = Q.front().y;
Q.pop();
if (is_Jimmy && ux == n) return 1; //检查是否到终点
if (!is_Jimmy && uy == n) return 1;
for (int i = 1, vx, vy; i <= 6; i++)
{
vx = ux + mx[i], vy = uy + my[i];
if (!vis[vx][vy] && G[vx][vy] == (is_Jimmy ? 1 : -1) && INRANGE(vx, vy))
{
vis[vx][vy] = 1;
Q.push({vx, vy});
}
}
}
return 0;
}
string Solve() //每一轮的处理
{
for (int i = 1; i <= n; i++)
{
if (G[1][i] == 1) if (BFS(1, i, 1)) return "Jimmy";
if (G[i][1] == -1) if (BFS(i, 1, 0)) return "Chen";
}
return "yet";
}
signed main()
{
io.read(T);
while (T--)
{
memset(G, 0, sizeof G); //多测清空
io.read(n);
for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) io.read(G[i][j]);
cout << Solve() << "\n";
}
}