P1379 八数码难题

普通的bfs相信都会吧QAQ,这里讲一个算是优化的方案…
先构建这么一张表格

0 1 2
3 4 5
6 7 8

找找规律…
可以发现

0%3 1%3 2%3
3%3 4%3 5%3
6%3 7%3 8%3
=>
0 1 2
0 1 2
0 1 2

每一列都一样QAQ

0/3 1/3 2/3
3/3 4/3 5/3
6/3 7/3 8/3
=>
0 0 0
1 1 1
2 2 2

每一行都一样QAQ
这样可以稍微优化一下代码看起来更高端

#include<bits/stdc++.h>//不多讲的万头
using namespace std;
const int Max=9*9*9*9*9*9*9;//和九数码一样QAQ
int now[Max][9],r[9],u[Max],zero[Max];//貌似都差不多
bool boo[9][9][9][9][9][9][9][9];//。。。
int i,j,k,m,n,h=1,t=1,x;
char s[9];
int main()
{
  cin>>s;//读入
  for(i=0;i<9;i++)r[i]=s[i]-'0';//存到数组
  for(i=0;i<9;i++)if(r[i]==0)zero[1]=i;//找到0的位置
  h=1;t=1;u[1]=0;
  for(k=0;k<9;k++)now[h][k]=r[k];
  boo[now[t][0]][now[t][1]][now[t][2]][now[t][3]][now[t][4]][now[t][5]][now[t][6]][now[t][7]]=true;
  while(t<=h)
  {
    if(now[t][0]==1&&now[t][1]==2&&now[t][2]==3&&now[t][3]==8&&now[t][4]==0&&now[t][5]==4&&now[t][6]==7&&now[t][7]==6)//找到解了QAQ
    {cout<<u[t];return 0;}
    if(zero[t]%3!=2)//如上表所示,当0的位置%3!=2时可以向右移动0,下同...
    {
      {for(k=0;k<9;k++)r[k]=now[t][k];
      r[zero[t]]=r[zero[t]+1];r[zero[t]+1]=0;
      if(!boo[r[1]][r[2]][r[3]][r[4]][r[5]][r[6]][r[7]][r[8]])
      {h++;u[h]=u[t]+1;zero[h]=zero[t]+1;
      for(k=0;k<9;k++)now[h][k]=r[k];
      boo[r[1]][r[2]][r[3]][r[4]][r[5]][r[6]][r[7]][r[8]]=true;}}
    }
    if(zero[t]%3!=0)//向左
    {
      {for(k=0;k<9;k++)r[k]=now[t][k];
      r[zero[t]]=r[zero[t]-1];r[zero[t]-1]=0;
      if(!boo[r[1]][r[2]][r[3]][r[4]][r[5]][r[6]][r[7]][r[8]])
      {h++;u[h]=u[t]+1;zero[h]=zero[t]-1;
      for(k=0;k<9;k++)now[h][k]=r[k];
      boo[r[1]][r[2]][r[3]][r[4]][r[5]][r[6]][r[7]][r[8]]=true;}}
    }
    if(zero[t]/3!=2)//向上
    {
      {for(k=0;k<9;k++)r[k]=now[t][k];
      r[zero[t]]=r[zero[t]+3];r[zero[t]+3]=0;
      if(!boo[r[1]][r[2]][r[3]][r[4]][r[5]][r[6]][r[7]][r[8]])
      {h++;u[h]=u[t]+1;zero[h]=zero[t]+3;
      for(k=0;k<9;k++)now[h][k]=r[k];
      boo[r[1]][r[2]][r[3]][r[4]][r[5]][r[6]][r[7]][r[8]]=true;}}
    }
    if(zero[t]/3!=0)//向下
    {
      {for(k=0;k<9;k++)r[k]=now[t][k];
      r[zero[t]]=r[zero[t]-3];r[zero[t]-3]=0;
      if(!boo[r[1]][r[2]][r[3]][r[4]][r[5]][r[6]][r[7]][r[8]])
      {h++;u[h]=u[t]+1;zero[h]=zero[t]-3;
      for(k=0;k<9;k++)now[h][k]=r[k];
      boo[r[1]][r[2]][r[3]][r[4]][r[5]][r[6]][r[7]][r[8]]=true;}}
    }
    t++;
  }
  return 0;
}//结束了QAQ

其实部分代码是P2578 九数码游戏抄的QAQ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值