ACM-双向BFS之魔板——求助ING!

魔板

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

给你魔板的初始状态与目标状态,请给出由初态到目态变换数最少的变换步骤,若有多种变换方案则取字典序最小的那种。

Input

每组测试数据包括两行,分别代表魔板的初态与目态。

Output

对每组测试数据输出满足题意的变换步骤。

Sample Input

12345678
17245368
12345678
82754631

Sample Output

C
AC

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1430

这道题,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;
}

ACM-双向BFS之魔板——求助ING!

时间: 2024-10-15 02:07:54

ACM-双向BFS之魔板——求助ING!的相关文章

ACM-康托展开+预处理BFS之魔板——hdu1430

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1679    Accepted Submission(s): 354 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版--魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜

HDU - 1430 - 魔板( 康托展开 + BFS预处理 )

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4242    Accepted Submission(s): 1011 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版--魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜

Hdoj 1430 魔板 【BFS】+【康拓展开】+【预处理】

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2139    Accepted Submission(s): 452 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版--魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜

BFS [HDU 1430] 魔板

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1988    Accepted Submission(s): 407 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜色

【判重+广搜(bfs)】魔板

判重+广搜(bfs)]魔板 Time Limit: 1000MS Memory Limit: 32768KB Special Judge 有一个两行四列的魔板,每个格子里有一个1到8的数字(数字唯一),现在我们可以对魔板进行以下操作: 1.交换两行的数字. 2.将第一列移到第二列,第二列到第三列,第三列到第四列,第四列到第一列. 3.将中间四个数顺时针转一次. 现给你初始状态,我末状态请你用最小的步数将它从初始状态变到末状态. 输入: 前两行,每行4个数表示初状态. 后两行,每行4个数表示末状态

HDU 1430 魔板(康托展开+BFS+预处理)

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2921    Accepted Submission(s): 649 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜

【搜索】魔板问题(BFS)

[搜索]魔板问题 时间限制: 1 Sec  内存限制: 64 MB提交: 5  解决: 3[提交][状态][讨论版] 题目描述 据说能使持有者成为世界之主的上古神器隐藏在魔板空间,魔板由8个同样大小的方块组成,每个方块颜色均不相同,按顺时针方向依次写下各方块的颜色代号,例如序列(1,2,3,4,5,6,7,8)即代表图所示的魔板状态. 对于魔板可施加三种不同的操作,分别以A,B,C标识,具体操作方法如图所示. 对于每种可能的状态,这三种基本操作都可以使用.你要编程计算用最少的基本操作完成基本状态

hdu.1430.魔板(bfs + 康托展开)

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2170    Accepted Submission(s): 455 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜

hdu1430魔板(广搜+康托展开+string应用)

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 2420    Accepted Submission(s): 511 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜色