zoukankan      html  css  js  c++  java
  • hdu1043 经典的八数码问题 逆向bfs打表 + 逆序数

    题意: 题意就是八数码,给了一个3 * 3 的矩阵,上面有八个数字,有一个位置是空的,每次空的位置可以和他相邻的数字换位置,给你一些起始状态 ,给了一个最终状态,让你输出怎么变换才能达到目的.


    思路: 首先我们先判断一下可不可以达到最终目的,方法是根据逆序数,只要终止状态和起始状态的逆序数(空的位置不算)奇偶性相同就能,否则不能;

    证明 :

    加入当前空的位置是i,针对3 * 3 的也就是八数码问题(可能有别的数码,根据奇偶性答案不同) 如果向前或向后移动的话 当前的逆序数不变,如果像上移动的话有三种情况, 移动过来的这个数比那两个数都大,逆序数 - 2 ,移动过来的这个数比那两个数都小 逆序数 + 2,比一个大,比另一个小,逆序数 + 1 - 1 不变,所以怎么移动逆序数奇偶性不变,所以只有起始状态可终止状态逆序数奇偶性相同才能转换..

    解决了判断,剩下的就是输出方法了,直接暴搜会TLE出"翔"来(测试数据太多),我们观察会发现,题目最终的目的地是同一个状态,无论什么最后都要到题目中给的那个终点,那么我们可以直接以终点为起点,遍历一边所有状态,然后把它存起来,等问的时候我们只要把存的方法变换一下就ok了,首先把整个序列颠倒过来,因为我们是反向打表,然后相应的 上 变 下 下 变 上 ... 因为是反向搜索..然后输出来就ok了, 这让我想起了以前做过的一道最短路,一群牛去一个地方开会,在回来问所有路径的最短和,路是单向的,我们只要直接以开会点为起点,跑两边最短路就ok了..想法是一样的.上代码.



    //逆向BFS打表 AC 


    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<map>
    #include<queue>


    using namespace std;


    typedef struct
    {
       int now_map[10];
       string root;
       int id0;
    }NODE;


    map<int ,string>ans_map;
    map<int ,int>mk;
    NODE xin ,tou;
    char ans[800000];
    int end_map[10] = {0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,0};


    bool hash(int now[] ,string root)
    {
       int sum = 0 ,e = 1;
       for(int i = 1 ;i <= 9 ;i ++)
       {
          sum += e * now[i];
          e *= 10;
       }
       if(mk[sum])
       return 1;
       mk[sum] = 1;
       ans_map[sum] = root;
       return 0;
    }


    void DB_BFS()
    {
       for(int i = 1 ;i <= 9 ;i ++)
       xin.now_map[i] = end_map[i];
       xin.root = "";
       xin.id0 =  9;
       queue<NODE>q;
       q.push(xin);
       ans_map.clear();
       mk.clear();
       hash(xin.now_map ,"ud");
       while(!q.empty())
       {
          tou = q.front();
          q.pop(); 
              
          if(tou.id0 >= 4)
          {
             xin = tou;
             xin.root = tou.root + 'u';
             xin.now_map[xin.id0] = tou.now_map[xin.id0-3];
             xin.now_map[xin.id0-3] = 0;
             xin.id0 -= 3;     
             if(!hash(xin.now_map ,xin.root))
             {           
                q.push(xin);
             }
         }
           
          if(tou.id0 <= 6)
          {
             xin = tou;
             xin.root = tou.root + 'd';
             xin.now_map[xin.id0] = tou.now_map[xin.id0+3];
             xin.now_map[xin.id0+3] = 0;
             xin.id0 += 3;
             if(!hash(xin.now_map ,xin.root))
             {
                q.push(xin);
             }   
          }
          
          if(tou.id0 != 1 && tou.id0 != 4 && tou.id0 != 7)
          {
             xin = tou;
             xin.root = tou.root + 'l';
             xin.now_map[xin.id0] = tou.now_map[xin.id0-1];
             xin.now_map[xin.id0-1] = 0;
             xin.id0 --;
             if(!hash(xin.now_map ,xin.root))
             {
                q.push(xin);                
             }
          }
          
          if(tou.id0 != 3 && tou.id0 != 6 && tou.id0 != 9)
          {
             xin = tou;
             xin.root = tou.root + 'r';
             xin.now_map[xin.id0] = tou.now_map[xin.id0+1];
             xin.now_map[xin.id0+1] = 0;
             xin.id0 ++;    
             if(!hash(xin.now_map ,xin.root))
             {
                q.push(xin);                
             }
          }
       }
    }


    int main ()
    {
       int i ,id0;
       char str[5];
       DB_BFS();
       NODE A;
       while(~scanf("%s" ,str))
       {
          if(str[0] == 'x')
          {
             A.id0 = 1;
             A.now_map[1] = 0;
          }
          else
          A.now_map[1] = str[0] - 48;
          for(i = 2 ;i <= 9 ;i ++)
          {
             scanf("%s" ,str);
             if(str[0] == 'x')
             {
                A.id0 = i;
                A.now_map[i] = 0;
             }
             else
             A.now_map[i] = str[0] - 48;
          }
          
          int sum = 0;
          int ss = 0 ,e = 1;
          for(i = 1 ;i <= 9 ;i ++)
          {
             ss += A.now_map[i] * e;
             e *= 10;
             if(!A.now_map[i])continue;
             for(int j = 1 ;j < i ;j ++)
             if(A.now_map[i] < A.now_map[j])
             sum ++;
          }
          if(sum % 2)
          {
             printf("unsolvable ");
             continue;
          }
          
          int l = ans_map[ss].length();   
          for(i = 0 ;i < l ;i ++)
          {
             char c = ans_map[ss][l-i-1];
             if(c == 'u')
             ans[i] = 'd';
             if(c == 'd')
             ans[i] = 'u';
             if(c == 'l')
             ans[i] = 'r';
             if(c == 'r')
             ans[i] = 'l';
          }
          ans[l] = '';
          puts(ans);
          
       }
       return 0;
    }     
       


  • 相关阅读:
    codeforce 1B
    codeforce A. Accounting
    20145208 《Java程序设计》第9周学习总结
    20145208 实验三 Java面向对象程序设计
    20145208 《Java程序设计》第8周学习总结
    20145208 《Java程序设计》第7周学习总结
    20145208 实验二 Java面向对象程序设计
    20145208实验一 Java开发环境的熟悉
    20145208 《Java程序设计》第6周学习总结
    20145208 《Java程序设计》第5周学习总结
  • 原文地址:https://www.cnblogs.com/csnd/p/12063310.html
Copyright © 2011-2022 走看看