Solitaire
*Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7782 Accepted Submission(s): 2276
*
Problem Description
Solitaire is a game played on a chessboard 8x8. The rows and columns of the chessboard are numbered from 1 to 8, from the top to the bottom and from left to right respectively.
There are four identical pieces on the board. In one move it is allowed to:
> move a piece to an empty neighboring field (up, down, left or right),
> jump over one neighboring piece to an empty field (up, down, left or right).
There are 4 moves allowed for each piece in the configuration shown above. As an example let’s consider a piece placed in the row 4, column 4. It can be moved one row up, two rows down, one column left or two columns right.
Write a program that:
> reads two chessboard configurations from the standard input,
> verifies whether the second one is reachable from the first one in at most 8 moves,
> writes the result to the standard output.
Input
Each of two input lines contains 8 integers a1, a2, …, a8 separated by single spaces and describes one configuration of pieces on the chessboard. Integers a2j-1 and a2j (1 <= j <= 4) describe the position of one piece - the row number and the column number respectively. Process to the end of file.
Output
The output should contain one word for each test case - YES if a configuration described in the second input line is reachable from the configuration described in the first input line in at most 8 moves, or one word NO otherwise.
Sample Input
4 4 4 5 5 4 6 5
2 4 3 3 3 6 4 6
Sample Output
YES
Source
Submit
//双向广搜
#include <bits/stdc++.h>
using namespace std;
char vis[8][8][8][8][8][8][8][8]; //记录四个棋子的状态
int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; //上下左右
struct point
{
int x;
int y;
};
bool cmp(point a, point b)
{
if (a.x == b.x)
return a.y < b.y;
return a.x < b.x;
}
struct state
{
point p[4]; //把四个棋子的位置都存进去
int step; //记录步数
};
int judge(state &s, int i, int j, int flag)
{
if (flag == 1)
{
if (s.step >= 4) //超过四步就返回
return 0;
s.step++;
}
s.p[i].x += dir[j][0];
s.p[i].y += dir[j][1];
if (s.p[i].x >= 0 && s.p[i].x < 8 && s.p[i].y >= 0 && s.p[i].y < 8)
{ //判断是否出界
int k;
for (k = 0; k < 4; k++)
{
if (i != k)
{
if (s.p[i].x == s.p[k].x && s.p[i].y == s.p[k].y)
{ //判断这个棋子的四个方向是否有棋子
if (flag == 1)
return judge(s, i, j, 0); //判断跳过相邻棋子之后还是否有棋子
else
return 0;
}
}
}
if (k >= 4)
{ //符合条件可以走
sort(s.p, s.p + 4, cmp);
return 1;
}
}
return 0;
}
void dbfs(state s1, state s2)
{
queue<state> q1, q2;
state temp;
q1.push(s1); //入列
q2.push(s2);
vis[s1.p[0].x][s1.p[0].y][s1.p[1].x][s1.p[1].y][s1.p[2].x][s1.p[2].y][s1.p[3].x][s1.p[3].y] = '1';
vis[s2.p[0].x][s2.p[0].y][s2.p[1].x][s2.p[1].y][s2.p[2].x][s2.p[2].y][s2.p[3].x][s2.p[3].y] = '2';
while (!q1.empty() || !q2.empty())
{
if (!q1.empty())
{
for (int i = 0; i < 4; i++)
{ // i表示第i个棋子
for (int j = 0; j < 4; j++)
{ // j表示走的方向
temp = q1.front();
if (judge(temp, i, j, 1))
{
if (vis[temp.p[0].x][temp.p[0].y][temp.p[1].x][temp.p[1].y][temp.p[2].x][temp.p[2].y][temp.p[3].x][temp.p[3].y] == '1')
continue;
if (vis[temp.p[0].x][temp.p[0].y][temp.p[1].x][temp.p[1].y][temp.p[2].x][temp.p[2].y][temp.p[3].x][temp.p[3].y] == '2')
{
cout << "YES" << endl; //开始棋子的状态和结束棋子的状态相同
return;
}
q1.push(temp);
vis[temp.p[0].x][temp.p[0].y][temp.p[1].x][temp.p[1].y][temp.p[2].x][temp.p[2].y][temp.p[3].x][temp.p[3].y] = '1';
//在q1中搜索过要标记为1
}
}
}
q1.pop();
}
if (!q2.empty())
{
for (int i = 0; i < 4; i++)
{ // i表示第i个棋子
for (int j = 0; j < 4; j++)
{ // j表示走的方向
temp = q2.front();
if (judge(temp, i, j, 1))
{
if (vis[temp.p[0].x][temp.p[0].y][temp.p[1].x][temp.p[1].y][temp.p[2].x][temp.p[2].y][temp.p[3].x][temp.p[3].y] == '2')
continue;
if (vis[temp.p[0].x][temp.p[0].y][temp.p[1].x][temp.p[1].y][temp.p[2].x][temp.p[2].y][temp.p[3].x][temp.p[3].y] == '1')
{
cout << "YES" << endl; //开始棋子的状态和结束棋子的状态相同
return;
}
q2.push(temp);
vis[temp.p[0].x][temp.p[0].y][temp.p[1].x][temp.p[1].y][temp.p[2].x][temp.p[2].y][temp.p[3].x][temp.p[3].y] = '2';
//在q2中搜索过要标记为2
}
}
}
q2.pop();
}
}
cout << "NO" << endl; //没有一种情况符合条件
}
int main()
{
int x, y;
while (cin >> x >> y)
{
state s1, s2;
s1.p[0].x = x - 1;
s1.p[0].y = y - 1;
// bfs下标从0开始,所以所有的x和y都要减一
for (int i = 1; i < 4; i++)
{
cin >> x >> y;
s1.p[i].x = x - 1;
s1.p[i].y = y - 1;
}
for (int i = 0; i < 4; i++)
{
cin >> x >> y;
s2.p[i].x = x - 1;
s2.p[i].y = y - 1;
}
s1.step = 0; //初始化步数为0
s2.step = 0;
sort(s1.p, s1.p + 4, cmp);
/*for(int i=0;i<4;i++)可以验证一下是否排序成功
cout<<s1.p[i].x<<" "<<s1.p[i].y<<" ";
*/
sort(s2.p, s2.p + 4, cmp);
memset(vis, 0, sizeof(vis)); //初始化
dbfs(s1, s2);
}
return 0;
}