hdu1430(康拓展开+bfs打表)

本文探讨了HDU1430题目,这是一个关于魔板的问题。通过分析,发现暴力搜索的方法无法通过所有测试用例,而采用BFS打表的方法能够有效地解决这个问题,并成功通过了所有的测试数据。值得注意的是,对于特定的数据12345678 12345678,其正确答案是输出换行符。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

地址:http://acm.hdu.edu.cn/showproblem.php?pid=1430

魔板

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1527    Accepted Submission(s): 311


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
 


注意:12345678 12345678 这组数据答案是输出换行符。

暴力bfs不过,打表却过了o.0。。。

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
bool bg[45000];
struct node{
    char s[8],biao[500];
    int p;
}str[45000];
int jc(int a)
{
    int k=1;
    for(int i=2;i<=a;i++)
        k*=i;
    return k;
}
void bfs()
{
    queue<node> qi;
    node here,next;
    int bgnum,k;
    char st[]={"12345678"};
    strcpy(here.s,st);
    here.p=0;str[1]=here;
    bg[1]=false;
    qi.push(here);
    while(!qi.empty())
    {
        here=qi.front();
        qi.pop();
        next=here;
        next.p++;
        next.s[0]=here.s[7];
        next.s[1]=here.s[6];
        next.s[2]=here.s[5];
        next.s[3]=here.s[4];
        next.s[4]=here.s[3];
        next.s[5]=here.s[2];
        next.s[6]=here.s[1];
        next.s[7]=here.s[0];bgnum=0;
        for(int i=0;i<7;i++)
        {
            k=0;
            for(int j=i+1;j<8;j++)
                if(next.s[i]>next.s[j]) k++;
            bgnum+=k*jc(7-i);
        }bgnum++;
        if(bg[bgnum])
        {
            bg[bgnum]=false;
            next.biao[here.p]='A';
            str[bgnum]=next;
            qi.push(next);
        }
        next.s[0]=here.s[3];
        next.s[1]=here.s[0];
        next.s[2]=here.s[1];
        next.s[3]=here.s[2];
        next.s[4]=here.s[5];
        next.s[5]=here.s[6];
        next.s[6]=here.s[7];
        next.s[7]=here.s[4];bgnum=0;
        for(int i=0;i<7;i++)
        {
            k=0;
            for(int j=i+1;j<8;j++)
                if(next.s[i]>next.s[j]) k++;
            bgnum+=k*jc(7-i);
        }bgnum++;
        if(bg[bgnum])
        {
            bg[bgnum]=false;
            next.biao[here.p]='B';
            str[bgnum]=next;
            qi.push(next);
        }
        next.s[0]=here.s[0];
        next.s[1]=here.s[6];
        next.s[2]=here.s[1];
        next.s[3]=here.s[3];
        next.s[4]=here.s[4];
        next.s[5]=here.s[2];
        next.s[6]=here.s[5];
        next.s[7]=here.s[7];bgnum=0;
        for(int i=0;i<7;i++)
        {
            k=0;
            for(int j=i+1;j<8;j++)
                if(next.s[i]>next.s[j]) k++;
            bgnum+=k*jc(7-i);
        }bgnum++;
        if(bg[bgnum])
        {
            bg[bgnum]=false;
            next.biao[here.p]='C';
            str[bgnum]=next;
            qi.push(next);
        }
    }
}
int main()
{
    memset(bg,true,sizeof(bg));
    bfs();
    node st[3];
    while(scanf("%s%s",st[0].s,st[1].s)!=EOF)
    {
        for(int i=0;i<8;i++)
        {
            for(int j=0;j<8;j++)
            {
                if(st[1].s[j]==st[0].s[i])
                {
                    st[2].s[j]=i+1+'0';
                    break;
                }
            }
        }
        int bgnum=0;
        for(int i=0;i<7;i++)
        {
            int k=0;
            for(int j=i+1;j<8;j++)
                if(st[2].s[i]>st[2].s[j]) k++;
            bgnum+=k*jc(7-i);
        }bgnum++;
        for(int i=0;i<str[bgnum].p;i++)
            printf("%c",str[bgnum].biao[i]);
        printf("\n");
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值