携程2017春招编程题——拼图(BFS模板题)
来源:互联网 发布:mac选择office安装路径 编辑:程序博客网 时间:2024/05/08 15:10
携程2017春招编程题——拼图
题目
解题思路
基础的解决算法是BFS队列解决,但是会超时。所以需要去重。
去重要考虑格子重复的情况,
9个格子,所以拼图有9!种状态,建立visited[9!]布尔数组记录访问情况,如何判断两种状态是否相同呢,通过康托展开。
哇,这个康托展开就坑爹了,谁tm学过这个呀,搜了一下才发现原来康拓展开就是通过一个数字来表示一个序列的排列(建立了排列关系 <–> 数字的对应关系)。
康托展开
使用示例来帮助理解利用Cantor展开如何求解本问题。
假如序列s=[“A”,”B”,”C”,”D”]
需要求序列s’=[“D”,”A”,”B”,”C”]是序列s的全排列中的第几个排列,记作X(s’);
X(s’) =
3(在序列DABC中有3个比D小)*3!+
0(在剩下的序列ABC中有0个比A小)*2!+
0(在剩下的序列BC中有0个比B小)*1!+
0(在剩下的序列C中有0个比C小)*0!
=18
代码实现
Todo: 写得比较凌乱,后续会整理
import java.util.*;public class Main { private static int[][] sample = { {1,2,3},{4,5,6},{7,8,0} }; private static final int MAX_NUM = 362880; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int[][] matrix = new int[3][3]; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { matrix[i][j] = scanner.nextInt(); } } boolean visited[] = new boolean[MAX_NUM]; Arrays.fill(visited, false); Strategy strategy = new Strategy(0, matrix, 0); Queue<Strategy> queue = new LinkedList<>(); queue.offer(strategy); while (!queue.isEmpty()) { Strategy cur = queue.poll(); // 如果队列取出的访问过,则取下一个 if (visited[cantor(cur.matrix)]) { continue; } // 如果得到结果,就返回 if (validate(cur.matrix)) { System.out.println(cur.depth); return; } // 队列取出的结果进行四个方向的变换 for (int i = -2; i <= 2; i++) { if (0 - cur.orient == i) { continue; } Position p = findZero(cur.matrix); if (i == -2) { // 0往右移动 int[][] m = copy(cur.matrix); if (p.y < 2) { int mid = m[p.x][p.y]; m[p.x][p.y] = m[p.x][p.y+1]; m[p.x][p.y+1] = mid; Strategy s = new Strategy(i, m, cur.depth+1); queue.offer(s); } continue; } if (i == -1) { // 下移 int[][] m = copy(cur.matrix); if (p.x < 2) { int mid = m[p.x][p.y]; m[p.x][p.y] = m[p.x+1][p.y]; m[p.x+1][p.y] = mid; Strategy s = new Strategy(i, m, cur.depth+1); queue.offer(s); } continue; } if (i == 1) { // 上移 int[][] m = copy(cur.matrix); if (p.x > 0) { int mid = m[p.x][p.y]; m[p.x][p.y] = m[p.x-1][p.y]; m[p.x-1][p.y] = mid; Strategy s = new Strategy(i, m, cur.depth+1); queue.offer(s); } continue; } if (i == 2) { // 左移 int[][] m = copy(cur.matrix); if (p.y > 0) { int mid = m[p.x][p.y]; m[p.x][p.y] = m[p.x][p.y-1]; m[p.x][p.y-1] = mid; Strategy s = new Strategy(i, m, cur.depth+1); queue.offer(s); } continue; } } // 四个方向变换玩,cur就玩完了,记录下来 visited[cantor(cur.matrix)] = true; } System.out.println(-1); return; } private static int[][] copy(int[][] matrix) { int res[][] = new int[3][3]; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { res[i][j] = matrix[i][j]; } } return res; } private static boolean validate(int[][] matrix) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (sample[i][j] != matrix[i][j]) { return false; } } } return true; } private static Position findZero(int[][] matrix) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (matrix[i][j] == 0) { return new Position(i, j); } } } return null; } static class Strategy { int orient; // 1 -上 -1-下 2-左 -2-右 int matrix[][]; int depth; Strategy(int orient, int[][] matrix, int depth) { this.orient = orient; this.matrix = matrix; this.depth = depth; } } static class Position { int x; int y; public Position(int x, int y) { this.x = x; this.y = y; } } static int cantor(int[][] input) { int nums[] = new int[9]; for (int i = 0; i < 9; i++) { nums[i] = input[i/3][i%3]; } int fact[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880}; int ans = 0; for (int i = 0; i < 9; ++i) { int tmp = 0; for (int j = i + 1; j < 9; ++j) if (nums[j] < nums[i]) ++tmp; ans += tmp * fact[9 - i - 1]; } return ans; }}
阅读全文
0 0
- 携程2017春招编程题——拼图(BFS模板题)
- 买帽子——百度2017春招笔试真题编程题(一)
- 携程2017 校招编程题
- 2017百度春招编程题
- 网易2017春招实习生编程题
- 百度2017春招实习生编程题
- 2017网易春招编程题
- 百度2017春招实习生编程题
- 百度2017春招编程题
- 网易2017春招编程题集合
- 2017秋招编程题
- 2017招 银 编程题
- 【编程】2017年360春招编程题
- BFS【模板题】
- 网易2017春招笔试真题编程题集合——9.涂棋盘
- 网易2017春招笔试真题编程题集合——2.优雅的点
- Oil Deposits(BFS模板题)
- 百度2017春招笔试真题编程题集合
- 数据压缩 实验五 JPEG原理分析JPEG解码器的调试
- 网络编程入门
- QMetaObject::connectSlotsByName 分析
- eclipse 启动服务后,部署的文件一直是旧的文件的原因分析
- [BZOJ3876][AHOI2014]支线剧情-有下界的最小费用流
- 携程2017春招编程题——拼图(BFS模板题)
- java变量和运算符
- 利用LineBasedFrameDecoder解决TCP粘包问题
- 事务安全问题及面试题
- MySQL表的检查、修复、分析和优化
- java 远程调用及动态代理的应用
- jquery实现轮播图
- PAT程序设计考题——甲级1003(Emergency ) C++实现
- 猥琐的暴搜 NOIP2011 Mayan游戏