(简单搜索)
题意:4x4的棋盘上有X和Y两种棋子各若干枚,求最少移动多少次棋子可以达到胜利局面:有4个X或者4个Y连成一行、一列或者对角线(两条对角线都算胜利)。
思路:直接bfs搜索写起来~(在移动棋子位置后忘了移动回来到原来的状态,这个bug检查了我一个小时…还是太久没写代码了,这是个教训OTZ)
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#define LL long long
#define ull unsigned long long
using namespace std;
const int maxn = 50000000;
char mp[5][5];
int num_mp[5][5];
bool vis[maxn];
struct node{
int cur, step;
node(int a=0, int b=0):cur(a),step(b){}
};
queue<node> Q;
bool judge(int x) {
for(int i=0; i<4; i++) {
if(num_mp[i][0]==x && num_mp[i][1]==x && num_mp[i][2]==x && num_mp[i][3]==x) return 1;
if(num_mp[0][i]==x && num_mp[1][i]==x && num_mp[2][i]==x && num_mp[3][i]==x) return 1;
}
if(num_mp[0][0]==x && num_mp[1][1]==x && num_mp[2][2]==x && num_mp[3][3]==x) return 1;
if(num_mp[0][3]==x && num_mp[1][2]==x && num_mp[2][1]==x && num_mp[3][0]==x) return 1;
return 0;
}
int num_hash() {
int ret = 0;
for(int i=0; i<4; i++)
for(int j=0; j<4; j++) {
ret = 3*ret + num_mp[i][j];
}
return ret;
}
void get_num_mp(int t) {
for(int i=3; i>=0; i--) {
for(int j=3; j>=0; j--) {
num_mp[i][j] = t % 3;
t /= 3;
}
}
}
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
bool valid(int x) {
if(0 <= x && x < 4) return 1;
return 0;
}
int main() {
//freopen("in.txt","r",stdin);
while(scanf("%s",mp[0]) == 1) {
for(int i=1; i<4; i++)
scanf("%s",mp[i]);
int head = 0, ans = -1;
for(int i=0; i<4; i++)
for(int j=0; j<4; j++){
int t = 0;
if(mp[i][j] == 'X') t = 1;
if(mp[i][j] == 'Y') t = 2;
head = 3*head + t;
}
memset(vis, 0, sizeof(vis));
while(!Q.empty()) Q.pop();
Q.push(node(head, 0)); vis[head] = 1;
while(!Q.empty()) {
node nd = Q.front(); Q.pop();
get_num_mp(nd.cur);
//printf("------step: %d\n",nd.step);
if(judge(1) || judge(2)) {
ans = nd.step;
break ;
}
for(int i=0; i<4; i++)
for(int j=0; j<4; j++) if(num_mp[i][j] == 0) {
for(int k=0; k<4; k++) {
int nowx = i + dx[k], nowy = j + dy[k];
if(valid(nowx) && valid(nowy) && num_mp[nowx][nowy]) {
swap(num_mp[i][j], num_mp[nowx][nowy]);
int hs = num_hash();
swap(num_mp[i][j], num_mp[nowx][nowy]);
if(vis[hs]) continue ;
vis[hs] = 1;
Q.push(node(hs, nd.step+1));
}
}
}
}
printf("%d\n",ans);
}
return 0;
}