此题搞了个双向BFS以为能快点,不过效果似乎不太理想。
用mask与原状态进行异或得到下一个状态是关键。
用STL的话G++超时,C++过。
自己写队列的话都能过。
双向队列要注意每一次扩展时要记录下子代的个数,下一次搜索要将子代搜索完了才算完成一次扩展。
/*
ID:slowlight
PROG:
LANG:C++
DATE:
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
using namespace std;
typedef struct{
int x;
int y;
int state;
int step;
}LastStep;
const int MAXSIZE = ( 1 << 16 ) + 1;
const int mask[16] = {63624, 62532, 61986, 61713, 36744, 20292, 12066, 7953, 35064, 17652, 8946, 4593, 34959, 17487, 8751, 4383};
bool vis1[MAXSIZE];
bool vis2[MAXSIZE];
LastStep lastStep1[MAXSIZE];
LastStep lastStep2[MAXSIZE];
void print( int state , int init_state )
{
if( state == init_state )
{
return;
}
else
{
print( lastStep1[state].state, init_state );
printf("%d %d\n", lastStep1[state].x + 1, lastStep1[state].y + 1);
}
}
int main()
{
freopen("input.in", "r", stdin);
freopen("output.out", "w", stdout);
/*init*/
int i, j, k;
int temp;
int init_state;
int x, y;
char c;
queue< int > que1;
queue< int > que2;
init_state = 0;
/*input*/
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
scanf("%c", &c);
if( c == '+' )
{
init_state += ( 1 << ( 15 - ( i * 4 + j ) ) );
}
}
getchar();
}
/*BFS*/
vis1[init_state] = true;
vis2[0] = true;
for(i=0;i<=MAXSIZE;i++)
{
lastStep1[i].state = 0;
lastStep1[i].step = 0;
lastStep1[i].x = 0;
lastStep1[i].y = 0;
lastStep2[i].state = 0;
lastStep2[i].step = 0;
lastStep2[i].x = 0;
lastStep2[i].y = 0;
}
que1.push(init_state);
que2.push(0);
int L1 = 1;
int L2 = 1;
int cnt1;
int cnt2;
while( !que1.empty() || !que2.empty() )
{
int front1;
int front2;
if( que1.size() <= que2.size() )
{
/*que1*/
cnt1 = 0;
if( !L1 )
L1 = 1;
while( L1 )
{
if( !que1.empty() )
{
front1 = que1.front();
que1.pop();
if( vis2[front1] )
{
temp = front1;
break;
}
for(i=0;i<16;i++)
{
x = i / 4;
y = i % 4;
k = front1 ^ mask[i];
if( !vis1[k] )
{
vis1[k] = true;
que1.push( k );
lastStep1[k].x = x;
lastStep1[k].y = y;
lastStep1[k].state = front1;
lastStep1[k].step = lastStep1[front1].step + 1;
cnt1++;
}
}
L1--;
}
}
if( L1 )
{
break;
}
L1 = cnt1;
}
else
{
cnt2 = 0;
if( !L2 )
L2 = 1;
/*que2*/
while( L2 )
{
if( !que2.empty() )
{
front2 = que2.front();
que2.pop();
if( vis1[front2] )
{
temp = front2;
break;
}
for(i=0;i<16;i++)
{
x = i / 4;
y = i % 4;
k = front2 ^ mask[i];
if( !vis2[k] )
{
vis2[k] = true;
que2.push( k );
lastStep2[k].x = x;
lastStep2[k].y = y;
lastStep2[k].state = front2;
lastStep2[k].step = lastStep2[front2].step + 1;
cnt2++;
}
}
L2--;
}
}
if( L2 )
break;
L2 = cnt2;
}
}
printf("%d\n", lastStep1[temp].step + lastStep2[temp].step);
print(temp, init_state);
while( temp )
{
printf("%d %d\n", lastStep2[temp].x + 1, lastStep2[temp].y + 1);
temp = lastStep2[temp].state;
}
return 0;
}