九宫重排_康拓展开_bfs

历届试题 九宫重排

时间限制:1.0s   内存限制:256.0MB

问题描述

  如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。

  我们把第一个图的局面记为:12345678.
  把第二个图的局面记为:123.46758
  显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
  本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。

输入格式

  输入第一行包含九宫的初态,第二行包含九宫的终态。

输出格式

  输出最少的步数,如果不存在方案,则输出-1。

样例输入

12345678.
123.46758

样例输出

3

样例输入

13524678.
46758123.

样例输出

22

拿到这个题的时候没什么思路,之前也做过bfs的题,最大的问题在于状态的保存,后来看到有个编码题用到了康拓展开,豁然开朗,数学真的是奇妙啊!还有很多不知道的东西呢!

又知道了java的几个坑,哪怕是数组直接赋值也是赋的地址,添加到链表之类的也是地址,想要不受干扰只能手工拷贝。

  1 package study_code;
  2
  3 import java.util.LinkedList;
  4 import java.util.Queue;
  5 import java.util.Scanner;
  6
  7 public class 八数码 {
  8
  9     static int[] vis = new int [900900]; //判断哈希值是否被访问
 10     static int[] f = new int[9];    //保存阶乘
 11     static int end; //最终状态的哈希值
 12     static node start = new node();
 13     static String resPath;
 14     static int[][] dir = {{-1,0},{1,0},{0,-1},{0,1}};
 15     static char[] dirc = {‘U‘,‘D‘,‘L‘,‘R‘};
 16     static class node{
 17         int loc; //记录当前空格位置 用一个数字记录 1-9
 18         int s[]; //记录当前所有数字的位置
 19         int hashVal; //当前状态的哈希值
 20         String path = ""; //记录当前路径
 21         public node() {
 22         }
 23     }
 24
 25     public static void fac() {
 26         f[0] = 1;
 27         for (int i = 1; i < f.length; i++) {
 28             f[i] = f[i-1] * i;
 29         }
 30     }
 31
 32     //康拓展开
 33     public static int getHash(int[] s) {
 34         int res = 0;
 35         for (int i = 0; i < s.length; i++) {
 36             int index =0;
 37             for (int j = i+1; j < s.length; j++) {
 38                 if (s[j]<s[i]) {
 39                     index++;
 40                 }
 41             }
 42             res += index*f[9-1-i];
 43         }
 44         return res;
 45     }
 46
 47
 48     public static boolean bfs() {
 49         Queue<node> q = new LinkedList<node>();
 50         q.offer(start);
 51         vis[start.hashVal] = 1;
 52         while (!q.isEmpty()) {
 53             node cur = q.poll();
 54             vis[cur.hashVal] = 1;
 55             if (cur.hashVal == end) {
 56                 resPath = cur.path;
 57                 return true;
 58             }
 59             int x =cur.loc/3;
 60             int y =cur.loc%3;
 61             for (int i = 0; i < 4; i++) {
 62                 int tx = x + dir[i][0];
 63                 int ty = y + dir[i][1];
 64                 if (tx<0||ty<0||tx>=3||ty>=3) {
 65                     continue;
 66                 }
 67                 node temp = new node();
 68                 temp.loc = tx*3+ty;
 69                 temp.path = cur.path+dirc[i];
 70                 temp.s = cur.s.clone();
 71                 //交换空格的位置
 72                 temp.s[cur.loc] = temp.s[temp.loc];
 73                 temp.s[temp.loc] = 0;
 74
 75                 temp.hashVal = getHash(temp.s);
 76                 if (vis[temp.hashVal] == 1) {
 77                     continue;
 78                 }
 79                 q.offer(temp);
 80                 vis[temp.hashVal] = 1;
 81             }
 82         }
 83         return false;
 84
 85
 86
 87     }
 88     public static void main(String[] args) {
 89         Scanner sc = new Scanner(System.in);
 90         fac();
 91         String t = sc.nextLine();
 92         char[] c = t.toCharArray();
 93         int[] n = new int[c.length];
 94         for (int i = 0; i < c.length; i++) {
 95             if (c[i] == ‘.‘) {
 96                 n[i] = 0;
 97                 start.loc = i;
 98             }else {
 99                 n[i] = c[i] - ‘0‘;
100             }
101         }
102         start.s = n.clone();
103         start.hashVal = getHash(start.s);
104         t = sc.nextLine();
105         c = t.toCharArray();
106         n = new int[c.length];
107         for (int i = 0; i < c.length; i++) {
108             if (c[i] == ‘.‘) {
109                 n[i] = 0;
110             }else {
111                 n[i] = c[i] - ‘0‘;
112             }
113         }
114         end = getHash(n);
115         bfs();
116         System.out.println(resPath.length());
117     }
118 }
时间: 2024-08-26 08:17:57

九宫重排_康拓展开_bfs的相关文章

九宫重拍(bfs + 康拓展开)

问题描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成第二个图所示的局面. 我们把第一个图的局面记为:12345678. 把第二个图的局面记为:123.46758 显然是按从上到下,从左到右的顺序记录数字,空格记为句点. 本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达.如果无论多少步都无法到达,则输出-1. 输入格式 输入第一行包含九宫的初态,第二行包含九宫的终态. 输出格式 输出最

蓝桥杯 历届试题 九宫重排 经典八数码问题 A*算法+康托展开

历届试题 九宫重排 时间限制:1.0s   内存限制:256.0MB 问题描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成第二个图所示的局面. 我们把第一个图的局面记为:12345678. 把第二个图的局面记为:123.46758 显然是按从上到下,从左到右的顺序记录数字,空格记为句点. 本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达.如果无论多少步都无法到达,则输出-1. 输入格

九宫重排(搜索)

1581: 题目名称:九宫重排 时间限制: 1 Sec  内存限制: 128 MB提交: 2  解决: 1[提交] [状态] [讨论版] [命题人:外部导入] 题目描述 问题描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成第二个图所示的局面. 我们把第一个图的局面记为:12345678.把第二个图的局面记为:123.46758显然是按从上到下,从左到右的顺序记录数字,空格记为句点. 本题目的任务是已知

康拓展开与逆康拓展开

1.康托展开的解释 康托展开就是一种特殊的哈希函数 把一个整数X展开成如下形式: X=a[n]*n!+a[n-1]*(n-1)!+...+a[2]*2!+a[1]*1! 其中,a为整数,并且0<=a<i,i=1,2,..,n {1,2,3,4,...,n}表示1,2,3,...,n的排列如 {1,2,3} 按从小到大排列一共6个.123 132 213 231 312 321 . 代表的数字 1 2 3 4 5 6 也就是把10进制数与一个排列对应起来. 他们间的对应关系可由康托展开来找到.

算法笔记_183:历届试题 九宫重排(Java)

目录 1 问题描述 2 解决方案   1 问题描述 问题描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成第二个图所示的局面. 我们把第一个图的局面记为:12345678. 把第二个图的局面记为:123.46758 显然是按从上到下,从左到右的顺序记录数字,空格记为句点. 本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达.如果无论多少步都无法到达,则输出-1. 输入格式 输入第一行包含

ACM/ICPC 之 BFS(离线)+康拓展开 (HDU1430-魔板)

魔板问题,一道经典的康拓展开+BFS问题,为了实现方便,我用string类来表示字符串,此前很少用string类(因为不够高效,而且相对来说我对char数组的相关函数比较熟),所以在这里也发现了很多容易被忽视的问题. 对于康拓展开不太熟系的可以先参看一篇博客:http://blog.csdn.net/zhongkeli/article/details/6966805 关于sting类,大家要注意,在赋值的时候,其赋值位置不能与首位置间存在未赋值部分. 题目需要转换思路的地方是: 我们需要将起始魔

Hdoj 1430 魔板 【BFS】+【康拓展开】+【预处理】

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2139    Accepted Submission(s): 452 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版--魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜

全排序与康拓展开

全排列: n=3 123 132 213 231 312 321 (由1~n组成,且出现一次,从小到大排序(或从大到小排序,或不排序)) 求全排序: I. Dfs1 //全排序没有顺序 #include <iostream> using namespace std; long a[100],n; void swap(long &a,long &b) { long temp; temp=a; a=b; b=temp; } void dfs(long pos) { long i;

UVA 10085(bfs+康拓展开)八数码问题

Description Problem A The Most Distant State Input: standard input Output: standard output The 8-puzzle is a square tray in which eight square tiles are placed. The remaining ninth square is uncovered. Each tile has a number on it. A tile that is adj