题意: 题意就是八数码,给了一个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\n");

         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] = '\0';

      puts(ans);

      

   }

   return 0;

}     

   


hdu1043 经典的八数码问题 逆向bfs打表 + 逆序数的更多相关文章

  1. HDU1043 Eight(八数码:逆向BFS打表+康托展开)题解

    Eight Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  2. poj 1077-Eight(八数码+逆向bfs打表)

    The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've see ...

  3. 【双向广搜+逆序数优化】【HDU1043】【八数码】

    HDU上的八数码 数据强的一B 首先:双向广搜 先处理正向搜索,再处理反向搜索,直至中途相遇 visit 和 队列都是独立的. 可以用一个过程来完成这2个操作,减少代码量.(一般还要个深度数组) 优化 ...

  4. Eight(经典题,八数码)

    Eight Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  5. HDOJ-1043 Eight(八数码问题+双向bfs+高效记录路径+康拓展开)

    bfs搜索加记录路径 HDOJ-1043 主要思路就是使用双向广度优先搜索,找最短路径.然后记录路径,找到结果是打印出来. 使用康拓序列来来实现状态的映射. 打印路径推荐使用vector最后需要使用a ...

  6. hdu1043Eight (经典的八数码)(康托展开+BFS)

    建议先学会用康托展开:http://blog.csdn.net/u010372095/article/details/9904497 Problem Description The 15-puzzle ...

  7. HDU 1043 Eight 【经典八数码输出路径/BFS/A*/康托展开】

    本题有写法好几个写法,但主要思路是BFS: No.1 采用双向宽搜,分别从起始态和结束态进行宽搜,暴力判重.如果只进行单向会超时. No.2 采用hash进行判重,宽搜采用单向就可以AC. No.3 ...

  8. 【洛谷】P1379 八数码难题(bfs)

    题目 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局 ...

  9. hdu 1043 Eight (八数码问题)【BFS】+【康拓展开】

    <题目链接> 题目大意:给出一个3×3的矩阵(包含1-8数字和一个字母x),经过一些移动格子上的数后得到连续的1-8,最后一格是x,要求最小移动步数. 解题分析:本题用BFS来寻找路径,为 ...

随机推荐

  1. dubbo使用和配置讲解

    1. 分布式系统中相关概念 1.1 互联网项目特点及目标 1.1.1 特点: 用户多 流量大.并发高 海量数据 易受攻击 功能繁琐 变更快 1.1.2 指标及相关目标 互联网项目三高目标:高并发.高可 ...

  2. 【资源下载】Linux下的Hi3861一站式鸿蒙开发烧录(附工具)

    下载附件 2021春节前夕,华为发布了 HUAWEI DevEco Device Tool 2.0 Beta1,整体提供了异常强大的功能.得知消息后,我在第一时间带着无比兴奋的心情下载尝鲜,但结果却是 ...

  3. Python3基础-目录

    Python3基础-目录(Tips:长期更新Python3目录) 第一章 初识Python3  1.1 Python3基础-前言  1.2 Python3基础-规范 第二章 Python3内置函数&a ...

  4. Azure Front Door(一)为基于.net core 开发的Azure App Service 提供流量转发

    一,引言 之前我们讲解到使用 Azure Traffic Manager.Azure LoadBalancer.Azure Application Gateway,作为项目的负载均衡器来分发流量,转发 ...

  5. 浅谈.Net Core后端单元测试

    目录 1. 前言 2. 为什么需要单元测试 2.1 防止回归 2.2 减少代码耦合 3. 基本原则和规范 3.1 3A原则 3.2 尽量避免直接测试私有方法 3.3 重构原则 3.4 避免多个断言 3 ...

  6. jwt以及如何使用jwt实现登录

    目录 jwt的使用和使用jwt进行登录 什么是jwt jwt的组成 为什么选择jwt session的缺点 jwt的优点 一个jwt的工具类 将jwt和登录进行结合 axios方式将jwt放在head ...

  7. P2764 最小路径覆盖问题 题解(二分图)

    建图思路很明确,拆点跑最大匹配,但这明显是个二分图的题题解居然只有一篇匈牙利算法. 发一种和之前那篇匈牙利思路略有不同的题解. 本题的难点就是如何输出,那么我们不妨在建图的时候加入一个原则,即:连边时 ...

  8. CF533F Encoding 题解

    题目链接CF533F Encoding 提示1:   \(\mathcal O(26^2*n)\) 的算法可通过.常用的几种字符串匹配算法kmp,AC自动机,哈希都可以解决该问题 (后两者可以优化到 ...

  9. Codeforces Round #553 B. Dima and a Bad XOR

    题面: 传送门 题目描述: 题意很简单:在一个N*M的矩阵中(N行M列),问是否可以:每行选一个整数,使他们的异或和大于0.如果不可以,输出"NIE":如果可以,输出"T ...

  10. python-3-1

    一.布尔类型    布尔值为: True 和Flase 注:区分大小写,如果写true 和false   不代表布尔类型值 小于 大于 小于等于  大于等于  对应这些判断 一般就是用布尔类型进行判断 ...