hdu 1043 eight(poj 1077) (bfs)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef int State[9];
const int MAXSTATE=1000000;
State st[MAXSTATE],goal;
//int dist[MAXSTATE];

int vis[362880],fact[9];
const int dx[]={-1,1,0,0}; //u d l r //d u r l
const int dy[]={0,0,-1,1};
struct father
{
  int nfa;
  char op;
};
father fa[MAXSTATE];
void init_lookup_table()  //初始化查找表
{
  fact[0]=1;
  for(int i=1;i<9;i++) fact[i]=fact[i-1]*i;
}
int try_to_insert(int s)
{
  int code=0;
  for(int i=0;i<9;i++)
  {
    int cnt=0;
    for(int j=i+1;j<9;j++) if(st[s][j]<st[s][i]) cnt++;
    code+=fact[8-i]*cnt;
  }
  if(vis[code]) return 0;
  return vis[code]=1;
}
int find_id(int s)
{
  int code=0;
  for(int i=0;i<9;i++)
  {
    int cnt=0;
    for(int j=i+1;j<9;j++) if(st[s][j]<st[s][i]) cnt++;
    code+=fact[8-i]*cnt;
  }
  return code;
}
void bfs()
{
  init_lookup_table();
  int front=1,rear=2,z;
  int idfront=find_id(front);
  vis[idfront]=1;
  fa[idfront].nfa=-1;
  while(front<rear)
  {
    //printf("%d %d..\n",front,rear);
    State& s=st[front];
    idfront=find_id(front);
    for(z=0;z<9;z++) if(!s[z])break;//查找 0 的位置
    int x=z/3,y=z%3;
    for(int d=0;d<4;d++)  //d u r l
    {
      int newx=x+dx[d];
      int newy=y+dy[d];
      int newz=newx*3+newy;
      if(newx>=0&&newx<3&&newy>=0&&newy<3)
      {
        State & t=st[rear];
        memcpy(&t,&s,sizeof(s));
        t[newz]=s[z];
        t[z]=s[newz];
        /*for(int ii=0;ii<9;ii++)
        {
            printf("%d ",t[ii]);
        }
        printf("\n");*/
        if(try_to_insert(rear))
        {
          int idrear=find_id(rear);
          fa[idrear].nfa=idfront;
          //printf("%d %d...\n",rear,idrear);
          if(d==0) //d u r l
          {
              fa[idrear].op=‘d‘;
          }
          else if(d==1)
          {
            fa[idrear].op=‘u‘;
          }
          else if(d==2)
          {
            fa[idrear].op=‘r‘;
          }
          else if(d==3)
          {
            fa[idrear].op=‘l‘;
          }
          rear++;
        }
      }
    }
    front++;
  }
}
int main()
{
  //freopen("out.txt","w",stdout);
  int i;
  char temp;
  memset(fa,0,sizeof(fa));
  memset(vis,0,sizeof(vis));
  for(i=1;i<=8;i++) st[1][i-1]=i;
    st[1][8]=0;
  bfs();

  while(cin>>temp)
  {
    if(temp!=‘x‘) goal[0]=temp-‘0‘;
    else          goal[0]=0;
    for(i=1;i<9;i++)
    {
      cin>>temp;
      if(temp!=‘x‘) goal[i]=temp-‘0‘;
      else          goal[i]=0;
    }
    int code=0;
    for(int i=0;i<9;i++)
    {
     int cnt=0;
      for(int j=i+1;j<9;j++) if(goal[j]<goal[i]) cnt++;
     code+=fact[8-i]*cnt;
    }
    if(fa[code].nfa==0) printf("unsolvable\n");
    else
    {
       int now=code;
       while(1)
        {
         if(now==0) {printf("\n");break;}
           printf("%c",fa[now].op);
           now=fa[now].nfa;
        }
    }
  }
  return 0;
}

  

时间: 2024-10-10 09:25:55

hdu 1043 eight(poj 1077) (bfs)的相关文章

Oil Deposits(poj 1526 DFS入门题)

http://poj.org/problem?id=1562 Oil Deposits Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12595   Accepted: 6868 Description The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp wor

POJ 2329 (暴力+搜索bfs)

Nearest number - 2 Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 3943 Accepted: 1210 Description Input is the matrix A of N by N non-negative integers. A distance between two elements Aij and Apq is defined as |i ? p| + |j ? q|. Your pro

poj 1077 八数码(BFS+康托展开)

1 /* 2 题意:八数码问题,给出3*3的矩阵含1~8以及x,给出一个符合的解使得移动后的矩阵的顺序为1~8,最后为x 3 4 题解:BFS 5 需要用到康托展开来表示状态,不然数组无法完全表示所有状态,这样BFS就无法判断找不到解的情况(status 6 的0ms,0KB究竟是怎么做到的,简直不能想象=.=) 7 */ 8 #include <cstdio> 9 #include <cstring> 10 #include <queue> 11 #include &

POJ 1077 Eight(康托展开+BFS)

Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30176   Accepted: 13119   Special Judge Description The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've seen it. It is constructed with 15

HDU 1043 Eight八数码解题思路(bfs+hash 打表 IDA* 等)

题目链接 https://vjudge.net/problem/HDU-1043 经典的八数码问题,学过算法的老哥都会拿它练搜索 题意: 给出每行一组的数据,每组数据代表3*3的八数码表,要求程序复原为初始状态 思路: 参加网站比赛时拿到此题目,因为之前写过八数码问题,心中暗喜,于是写出一套暴力bfs+hash,结果TLE呵呵 思路一:bfs+hash(TLE) 1 #include <cstdio> 2 #include <cstring> 3 #include <queu

poj 1077 Eight(A*)

经典的八数码问题,用来练习各种搜索=_=.这题我用的A*做的,A*的主要思想就是在广搜的时候加了一个估价函数,用来评估此状态距离最终状态的大概距离.这样就可以省下很多状态不用搜索.对于每个状态设置一个函数 h(x),这就是估价函数了(可能名词不太对请见谅),再设置一个函数 g(x), 这存的是初始状态到当前状态所用步数(或距离,视估价函数而定),再设函数 f(x) = g(x) + h(x),我们对每个状态的 f(x)的值进行排序, 然后从当前 f(x) 最小的状态继续搜索,直到搜索到最终状态或

poj 1077 Eight(bfs,dbfs)

代码如下: dbfs: 1 #include <iostream> 2 #include <map> 3 #include <algorithm> 4 #include <string> 5 #include <queue> 6 using namespace std; 7 typedef long long LL; 8 9 int eight[3][3], xx, xy, dx[]={0,0,-1,1,0}, dy[]={0,1,0,0,-1}

POJ 1077 Eight(bfs+康托展开)

Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 41040   Accepted: 16901   Special Judge Description The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've seen it. It is constructed with 15

POJ 3083 Children of the Candy Corn(顺时针DFS+逆时针DFS+BFS)

题目链接:POJ 3083 Children of the Candy Corn [题意]给出一个迷宫,不超过40*40,'#'代表墙,'.'代表能走,'S'是起点,'E'是终点.分别求出从起点一直沿左走,一直沿右走,走到终点所需要的步数.以及走出迷宫的最小步数. [思路]首先最小步数很简单,一个普通BFS搞定,这道题重点是一直向左走和一直向右走的DFS的方向问题,方向还和游客当时朝向有关.开始一直认为是每次都向左(右)转,直到可以走,然后就一直不对,在google了之后才知道向左走要遵循左上右