ACM-双向BFS之魔板——求助ING!
时间:2014-05-01 17:38:02
收藏:0
阅读:315
魔板
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1675 Accepted Submission(s): 353
Problem Description
在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板。魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示。任一时刻魔板的状态可用方块的颜色序列表示:从魔板的左上角开始,按顺时针方向依次写下各方块的颜色代号,所得到的数字序列即可表示此时魔板的状态。例如,序列(1,2,3,4,5,6,7,8)表示魔板状态为:
1 2 3 4
8 7 6 5
对于魔板,可施加三种不同的操作,具体操作方法如下:
A: 上下两行互换,如上图可变换为状态87654321
B: 每行同时循环右移一格,如上图可变换为41236785
C: 中间4个方块顺时针旋转一格,如上图可变换为17245368
给你魔板的初始状态与目标状态,请给出由初态到目态变换数最少的变换步骤,若有多种变换方案则取字典序最小的那种。
1 2 3 4
8 7 6 5
对于魔板,可施加三种不同的操作,具体操作方法如下:
A: 上下两行互换,如上图可变换为状态87654321
B: 每行同时循环右移一格,如上图可变换为41236785
C: 中间4个方块顺时针旋转一格,如上图可变换为17245368
给你魔板的初始状态与目标状态,请给出由初态到目态变换数最少的变换步骤,若有多种变换方案则取字典序最小的那种。
Input
每组测试数据包括两行,分别代表魔板的初态与目态。
Output
对每组测试数据输出满足题意的变换步骤。
Sample Input
12345678 17245368 12345678 82754631
Sample Output
C AC
这道题,BFS会超时,于是我用的双向BFS。。。
这题目中的VIS要用到 康托展开(详情可戳 http://blog.csdn.net/lttree/article/details/24798653 )
我的思路:
因为字典序,所以按照A->B->C搜索。
q队列存正向搜索的,搜索过的置1,p队列存反向搜索的,搜索过的置2。(初始化为0)
每次都扩展一层结点。
输出的时候先输出 正向的答案 再反向 输出反向的答案。
VIS数组内存到达该点时的节点和标记(1或者2)
网上说用预处理来做,
但是我试了试发现双广不会超时,就是WA。。。快被虐呆了~~o(>_<)o ~~
求大神大牛们帮忙看一下。。。
#include <iostream>
#include <string.h>
#include <queue>
using namespace std;
struct Node
{
char board[8],key[101];
int step;
bool operator <( const Node n )const
{
return step<n.step;
}
};
struct VIS
{
int flag;
Node k;
}vis[40320+1];
int fac[] = {1,1,2,6,24,120,720,5040,40320};
char ini[8],ans[8];
// 康托展开
int kangtuo(char a[])
{
int i,j,t,sum;
sum=0;
for( i=0; i<8 ;++i)
{
t=0;
for(j=i+1;j<8;++j)
if( a[i]>a[j] )
++t;
sum+=t*fac[8-i-1];
}
return sum+1;
}
// 输出函数
void print( Node n,Node m )
{
int i;
for(i=0;i<n.step;++i)
cout<<n.key[i];
for(i=m.step-1;i>=0;--i)
cout<<m.key[i];
cout<<endl;
}
void bfs( void )
{
memset(vis,0,sizeof(vis));
priority_queue <Node> q;
priority_queue <Node> p;
Node pre,lst;
int i,sp=0;
// 初始化
for(i=0;i<8;++i)
pre.board[i]=ini[i];
pre.step=0;
vis[kangtuo(pre.board)].flag=1;
vis[kangtuo(pre.board)].k=pre;
q.push(pre);
for(i=0;i<8;++i)
pre.board[i]=ans[i];
pre.step=0;
vis[kangtuo(pre.board)].flag=2;
vis[kangtuo(pre.board)].k=pre;
p.push(pre);
// 双向BFS
while( !q.empty() && !p.empty() )
{
// 将每一层都扩展
while( q.top().step==sp )
{
pre=q.top();
q.pop();
// 按A方案变化
lst=pre;
for(i=0; i<8; ++i)
lst.board[i]=pre.board[7-i];
lst.key[lst.step++]=‘A‘;
if( vis[kangtuo(lst.board)].flag==2 )
{
print(lst,vis[kangtuo(lst.board)].k);
return;
}
if( !vis[kangtuo(lst.board)].flag )
{
vis[kangtuo(lst.board)].flag=1;
vis[kangtuo(lst.board)].k=lst;
q.push(lst);
}
// 按B方案变化
lst=pre;
for(i=0; i<8; ++i)
{
if(i==0) lst.board[i]=pre.board[3];
else if(i==7) lst.board[i]=pre.board[4];
else lst.board[i]=pre.board[i-1];
}
lst.key[lst.step++]=‘B‘;
if( vis[kangtuo(lst.board)].flag==2 )
{
print(lst,vis[kangtuo(lst.board)].k);
return;
}
if( !vis[kangtuo(lst.board)].flag )
{
vis[kangtuo(lst.board)].flag=1;
vis[kangtuo(lst.board)].k=lst;
q.push(lst);
}
// 按C方案变化
lst=pre;
lst.board[1]=pre.board[6];
lst.board[2]=pre.board[1];
lst.board[5]=pre.board[2];
lst.board[6]=pre.board[5];
lst.key[lst.step++]=‘C‘;
if( vis[kangtuo(lst.board)].flag==2 )
{
print(lst,vis[kangtuo(lst.board)].k);
return;
}
if( !vis[kangtuo(lst.board)].flag )
{
vis[kangtuo(lst.board)].flag=1;
vis[kangtuo(lst.board)].k=lst;
q.push(lst);
}
}
while( p.top().step==sp )
{
pre=p.top();
p.pop();
//A
lst=pre;
for(i=0; i<8; ++i)
lst.board[i]=pre.board[7-i];
if( vis[kangtuo(lst.board)].flag==1 )
{
print(vis[kangtuo(lst.board)].k,lst);
return;
}
if( !vis[kangtuo(lst.board)].flag )
{
lst.key[lst.step++]=‘A‘;
vis[kangtuo(lst.board)].flag=2;
vis[kangtuo(lst.board)].k=lst;
p.push(lst);
}
//B
lst=pre;
for(i=0; i<8; ++i)
{
if(i==0) lst.board[i]=pre.board[3];
else if(i==7) lst.board[i]=pre.board[4];
else lst.board[i]=pre.board[i-1];
}
if( vis[kangtuo(lst.board)].flag==1 )
{
print(vis[kangtuo(lst.board)].k,lst);
return;
}
if( !vis[kangtuo(lst.board)].flag )
{
lst.key[lst.step++]=‘B‘;
vis[kangtuo(lst.board)].flag=2;
vis[kangtuo(lst.board)].k=lst;
p.push(lst);
}
//C
lst=pre;
lst.board[1]=pre.board[6];
lst.board[2]=pre.board[1];
lst.board[5]=pre.board[2];
lst.board[6]=pre.board[5];
if( vis[kangtuo(lst.board)].flag==1 )
{
print(vis[kangtuo(lst.board)].k,lst);
return;
}
if( !vis[kangtuo(lst.board)].flag )
{
lst.key[lst.step++]=‘C‘;
vis[kangtuo(lst.board)].flag=2;
vis[kangtuo(lst.board)].k=lst;
p.push(lst);
}
}
++sp;
}
}
int main()
{
while( cin.getline(ini,10,‘\n‘) )
{
cin.getline(ans,10,‘\n‘);
bfs();
}
return 0;
}
评论(0)