CDOJ 训练搜索专题G 八数码固定终点问题

#include <map>
#include <set>
#include <list>
#include <cmath>
#include<cctype>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b)
{
return a % b == 0 ? b : gcd(b, a % b);
}
typedef int State[9];
#define  MAXSTATE 1000000
const int dx[]={0,0,-1,1};
const int dy[]={1,-1,0,0};
State des={1,2,3,4,5,6,7,8,0};
State q[MAXSTATE];
int dist[MAXSTATE];
int ans;
int Map[MAXSTATE];// 映射一下
int vis[362890],fac[9];
void init_lookup_table()
{
      fac[0]=1;
	  for (int i=1;i<9;i++)
	  fac[i]=fac[i-1]*i;
}
int hash(State s)
{
    int code=0;
	for (int i=0;i<9;i++)
    {
        int cnt=0;
        for (int j=0;j<i;j++)
        if (s[j]>s[i]) cnt++;
        code+=fac[i]*cnt;
    }
    return code;
}
void bfs()
{
    init_lookup_table();
	memcpy(&q[0],&des,sizeof(des));
	int front=0,rear=1;
	dist[0]=0;
	int tmp=hash(des);
	vis[tmp]=1;
	Map[tmp]=0;
	while (front<rear)
	{
		State& u=q[front];
		int z;
		for (z=0;z<9;z++) if (!u[z]) break;
		int x=z/3,y=z%3;
		for (int d=0;d<4;d++)
		{
			int nx=x+dx[d];
			int ny=y+dy[d];
			int nz=nx*3+ny;
			if (nx>=0 && nx<3 && ny>=0 && ny<3)
			{
			    State& s=q[rear];
			    memcpy(&s,&u,sizeof(u));
				s[nz]=u[z];
				s[z]=u[nz];
				//for (int i=0;i<9;i++) printf("%d ",s[i]);getchar();getchar();
				int T=hash(s);
				if (!vis[T])
				{
				 vis[T]=1;
				dist[rear]=dist[front]+1;
				 Map[T]=rear;
				 rear++;
			    }
			}
		}
		front++;
	}
}
void read(State &s)
{    int i;
    char c[5];
    for (i = 1; i < 9; i++)
    {
        scanf("%s", c);
        if (c[0] == 'x') s[i] = 0;
        else s[i] = c[0] - '0';
    }
}
int main()
{
     bfs();
     char c[5];
     while (scanf("%s",c)!=EOF)
     {
         State a;
     if (c[0] == 'x') a[0] = 0;
        else a[0] = c[0] - '0';
     read(a);
     int ans=hash(a);
     //printf("%d\n",ans);
     if (!vis[ans])
     printf("unsolvable\n");
     else
     printf("%d\n",dist[Map[ans]]);
     }
     return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值