AOJ0121——Seven Puzzle(BFS)

题目链接

      话说鄙人做这道题都有种把翔都做出来的感觉,主要是死在对string(一个自己不是很懂的东西)的不了解。然后一直在调bug,题意就是给你一个8宫格,然后0表示空缺,可以将相邻位的数字与空缺交换,以表示将该数字块移到空缺,然后会给你多组输入,每一组表示按从左到右,从上到下排列的8个数,问将这样排列的8个数移成01234567,最少移动多少步。输入有多组。先开始老老实实按题意从出发点开始移动,写完跑了一组就慢的不行了,再这玩意又是多组输入,所以从它给的输入开始搜,那岂不是超时妥妥的,后来看了下题解,才发现是要反的搞,何为反的搞,就是以01234567为出发点来BFS所有的可能,然后直接查找。这样搜一遍就OK了。

       主要蛋疼的是我用了string,先开始一直没对string初始化,也就是一开始只写了string s;而没有像下面的代码一样写成string s = "00000000"(切记此时一定要是8个数,无论这8个数是几都行,但一定要8个数,我这里就直接用了8个0),这样没初始化s的话,s默认是没有长度的,但是访问它的单个节点位置确实行的通的,比如访问是s[0],s[1],之类的是可以查看的,虽然这是非法的。但编译器还是会让你过,因为string是一个封装好的类,它是一棵树,有上限空间,这是事先开辟好的,但是并不能访问,或者说访问是非法的。只有当你初始化了一定空间,这段被初始化的空间访问才是合法的,所以当你直接调用s时,若没初始化是得不到正确结果的。此题给的数量是8个数,所以应该初始8个字符大小的合法空间。为了这个问题,调了将近两个小时也是没谁了,,,,以后还是多多注意的好。。。。



#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#include<algorithm>
#include<map>
#include<string>

using namespace std;

map<string,int>mp;
queue<string>q;
int mov[4]= {-1,1,-4,4};

void bfs()
{
    mp.clear();
    mp["01234567"]=1;
    q.push("01234567");
    while(!q.empty())
    {
        string s=q.front();
        q.pop();
        int f=0;
        for(int i=0; i<8; i++)
            if(s[i]=='0')
            {
                f=i;
                break;
            }
        for(int i=0;i<4;i++)
        {
            if(f+mov[i]<0||f+mov[i]>7||(f+mov[i]==4&&i==1)||(f+mov[i]==3&&i==0))continue;
            string t=s;
            swap(t[f],t[f+mov[i]]);
            if(mp[t]==0)
            {
                mp[t]=mp[s]+1;
                //cout<<t<<' '<<mp[t]<<endl;
                q.push(t);
            }
        }
    }
}

int main()
{
    //freopen("in.in","r",stdin);
    bfs();
    int t;
    string s="00000000";
    while(scanf("%d",&t)!=EOF)
    {
        s[0]=t+'0';
        for(int i=1;i<8;i++)
        {
            scanf("%d",&t);
            s[i]=t+'0';
        }
        /*for(int i=0;i<8;i++)
            printf("%c",s[i]);
        printf("\n");*/
        //cout<<s<<endl;
        printf("%d\n",mp[s]-1);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值