• Eight hdu 1043 poj 1077


    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 sliding tiles, each with a number from 1 to 15 on it, and all packed into a 4 by 4 frame with one tile missing. Let's call the missing tile 'x'; the object of the puzzle is to arrange the tiles so that they are ordered as:


    1 2 3 4
    5 6 7 8
    9 10 11 12
    13 14 15 x


    where the only legal operation is to exchange 'x' with one of the tiles with which it shares an edge. As an example, the following sequence of moves solves a slightly scrambled puzzle:


    1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
    5 6 7 8 5 6 7 8 5 6 7 8 5 6 7 8
    9 x 10 12 9 10 x 12 9 10 11 12 9 10 11 12
    13 14 11 15 13 14 11 15 13 14 x 15 13 14 15 x
    r-> d-> r->


    The letters in the previous row indicate which neighbor of the 'x' tile is swapped with the 'x' tile at each step; legal values are 'r','l','u' and 'd', for right, left, up, and down, respectively.

    Not all puzzles can be solved; in 1870, a man named Sam Loyd was famous for distributing an unsolvable version of the puzzle, and
    frustrating many people. In fact, all you have to do to make a regular puzzle into an unsolvable one is to swap two tiles (not counting the missing 'x' tile, of course).

    In this problem, you will write a program for solving the less well-known 8-puzzle, composed of tiles on a three by three
    arrangement.

    Input

    You will receive, several descriptions of configuration of the 8 puzzle. One description is just a list of the tiles in their initial positions, with the rows listed from top to bottom, and the tiles listed from left to right within a row, where the tiles are represented by numbers 1 to 8, plus 'x'. For example, this puzzle

    1 2 3
    x 4 6
    7 5 8

    is described by this list:

    1 2 3 x 4 6 7 5 8

    Output

    You will print to standard output either the word ``unsolvable'', if the puzzle has no solution, or a string consisting entirely of the letters 'r', 'l', 'u' and 'd' that describes a series of moves that produce a solution. The string should include no spaces and start at the beginning of the line. Do not print a blank line between cases.

    Sample Input

    2 3 4 1 5 x 7 6 8

    Sample Input

    2 3 4 1 5 x 7 6 8
    题意 : 就是8数码问题,主要时搜索的路径寻找问题,把'x'转换为0,然后把当前这些数都存储为1个状态
    分析: 这道题有两道相同的,分别是HDU和POJ,HDU上的数据加强了比POJ更麻烦。。
    POJ:正向搜索就好(简单)
      1 #include <iostream>  
      2 #include <cstring>  
      3   
      4 using namespace std;  
      5   
      6 const int maxn = 1000003;  
      7 typedef int State[9];  
      8 State st[maxn];  
      9 int goal[] = {1, 2, 3, 4, 5, 6, 7, 8, 0};  
     10 int dx[] = {-1, 1,  0, 0};  
     11 int dy[] = { 0, 0, -1, 1};  
     12 int head[maxn], nxt[maxn], fa[maxn];  
     13 char dir[maxn];  
     14   
     15 int Hash(State s)       //哈希函数  
     16 {  
     17     int ret = 0, i;  
     18     for(i = 0; i < 9; i++) ret = ret * 10 + s[i];  
     19     return ret % maxn;  
     20 }  
     21   
     22 bool try_to_insert(int rear)        //插入哈希表  
     23 {  
     24     int h = Hash(st[rear]);  
     25     for(int e = head[h]; e != -1; e = nxt[e])  
     26     {  
     27         if(memcmp(st[e], st[rear], sizeof(st[e])) == 0) return 0;  
     28     }  
     29     nxt[rear] = head[h];  
     30     head[h] = rear;  
     31     return 1;  
     32 }  
     33   
     34 int bfs()       //遍历  
     35 {  
     36     int frt = 1, rear = 2, i, z;  
     37     while(frt < rear)  
     38     {  
     39         State& s = st[frt];  
     40         if(memcmp(s, goal, sizeof(s)) == 0) return frt;  
     41         for(z = 0; s[z] != 0; z++);  
     42         int x = z / 3;  
     43         int y = z % 3;  
     44         for(i = 0; i < 4; i++)  
     45         {  
     46             int newx = x + dx[i];  
     47             int newy = y + dy[i];  
     48             int newz = 3 * newx + newy;  
     49             if(newx >= 0 && newx < 3 && newy >= 0 && newy < 3)  
     50             {  
     51                 State& news = st[rear];  
     52                 memcpy(news, s, sizeof(s));  
     53                 news[z] = s[newz];  
     54                 news[newz] = 0;  
     55                 if(try_to_insert(rear))     //注意这里的路径输出的方式
     56                 {  
     57                     fa[rear] = frt;  
     58                     switch(i)  
     59                     {  
     60                         case 0: dir[rear] = 'u'; break;  
     61                         case 1: dir[rear] = 'd'; break;  
     62                         case 2: dir[rear] = 'l'; break;  
     63                         case 3: dir[rear] = 'r'; break;  
     64                         default: break;  
     65                     }  
     66                     rear++;  
     67                 }  
     68             }  
     69         }  
     70         frt++;  
     71     }  
     72     return 0;  
     73 }  
     74   
     75 void print(int i)       //输出  
     76 {  
     77     if(fa[i] == -1) return;  
     78     print(fa[i]);  
     79     cout<<dir[i];  
     80 }  
     81   
     82 int main()  
     83 {  
     84     char c[10];  
     85     int i, ret;  
     86     while(cin>>c[0]>>c[1]>>c[2]>>c[3]>>c[4]>>c[5]>>c[6]>>c[7]>>c[8])  
     87     {  
     88         for(i = 0; i < 9; i++) st[1][i] = c[i] == 'x' ? 0 : (int)(c[i]-'0');  
     89         memset(head, -1, sizeof(head));  
     90         fa[1] = -1;  
     91         ret = bfs();  
     92         if(ret)  
     93         {  
     94             print(ret);  
     95         }  
     96         else cout<<"unsolvable";  
     97         cout<<endl;  
     98     }  
     99     return 0;  
    100 }

    HDU : 这道题时多组输入,所以不能向上面一样在线写,而是要从最终状态开始倒着把所有状态搜索一遍,之后只需要输入初始状态打表判断输出路径即可;

      学习到的知识有两个:bfs()路径查找类 + 康拓展开,路径的输出:

      1 /*************************************************************************
      2     > File Name: search.cpp
      3     > Author : PrayG
      4     > Mail: 996930051@qq,com
      5     > Created Time: 2016年07月20日 星期三 10时56分09秒
      6  ************************************************************************/
      7 
      8 #include<iostream>
      9 #include<cstdio>
     10 #include<cstring>
     11 #include<string>
     12 #include<queue>
     13 #include<algorithm>
     14 #include<map>
     15 #include<stack>
     16 #include<set>
     17 #include<cmath>
     18 using namespace std;
     19 const int maxn = 362900;
     20 int fac[] = {1,1,2,6,24,120,720,5040,40320,362880};
     21 int dx[] = {1,0,-1,0},dy[] = {0,1,0,-1};//drul
     22 char ind[5] = "uldr";//与上面相反
     23 string path[maxn];//记录路径
     24 bool vis[maxn];
     25 int aim = 46233;//123456780 的康拓展开
     26 
     27 struct node
     28 {
     29     int s[9];  //记录状态
     30     int sit0;  //0 的位置
     31     int val;   //康拓展开的值
     32     string path;  // 路径
     33 };
     34 
     35 int cant(int s[])  //康拓展开
     36 {
     37     int code = 0;
     38     for(int i = 0; i < 9; i++)
     39     {
     40         int cnt = 0;
     41         for(int  j= i+1 ; j < 9; j++)
     42         {
     43             if(s[i] > s[j])
     44             {
     45                 cnt++;
     46             }
     47         }
     48         code += fac[8-i] * cnt;
     49     }
     50     return code;
     51 }
     52 
     53 void bfs()
     54 {
     55     memset(vis,false,sizeof(vis));
     56     queue<node> que;
     57     node cnt1,cnt2;
     58     for(int i = 0 ; i < 8;i++)
     59       cnt1.s[i] = i+1;
     60     cnt1.s[8] = 0;
     61     cnt1.sit0 = 8;
     62     //printf("aim = %d
    ",aim);
     63     cnt1.val = aim;
     64     cnt1.path = "";
     65     path[aim] = "";
     66     que.push(cnt1);
     67     while(!que.empty())
     68     {
     69         cnt1 = que.front();
     70         que.pop();
     71         int x = cnt1.sit0 / 3;
     72         int y = cnt1.sit0 % 3;
     73         for(int i = 0; i < 4; i++)
     74         {
     75             int nx = x + dx[i];
     76             int ny = y + dy[i];
     77             int nz = nx * 3 + ny;
     78             if(nx < 0 || nx >2 || ny <0 || ny >2)
     79                continue;
     80             cnt2 = cnt1;
     81             cnt2.s[cnt1.sit0] = cnt2.s[nz];
     82             cnt2.s[nz] = 0;
     83             cnt2.sit0 = nz;
     84             cnt2.val = cant(cnt2.s);
     85             if(!vis[cnt2.val])
     86             {
     87                 vis[cnt2.val] = true;
     88                 cnt2.path = ind[i] + cnt1.path;
     89                 que.push(cnt2);
     90                 path[cnt2.val] = cnt2.path;
     91             }
     92         }
     93 
     94     }
     95 }
     96 
     97 int main()
     98 {
     99     bfs();
    100     char t;
    101     while(cin >> t)
    102     {
    103         node st;
    104         if(t == 'x'){
    105           st.s[0] = 0;
    106             st.sit0 = 0;
    107         }
    108         else
    109         st.s[0] = t - '0';
    110         for(int i = 1; i< 9; i++)
    111         {
    112             cin >> t;
    113             if(t == 'x')
    114             {
    115                 st.s[i] = 0;
    116                 st.sit0 = i;
    117             }
    118             else
    119              st.s[i] = t -'0';
    120         }
    121         st.val = cant(st.s);
    122         if(vis[st.val])
    123         {
    124             cout << path[st.val] << endl;
    125         }
    126         else
    127          cout << "unsolvable" << endl;
    128     }
    129     return 0;
    130 }
     
     
  • 相关阅读:
    day01的那些事
    Activity活动
    开始认真学习Android了
    《知其所以然》读书笔记
    网络编程——完成端口
    开发服务器端——工程配置
    完善自己的学习方法
    WSAAsyncSelect模型
    双缓冲绘图
    ListControl常用操作汇总
  • 原文地址:https://www.cnblogs.com/PrayG/p/5697474.html
Copyright © 2020-2023  润新知