题目:

Let's play a card game called Gap. 
You have 28 cards labeled with two-digit numbers. The first digit (from 1 to 4) represents the suit of the card, and the second digit (from 1 to 7) represents the value of the card. 

First, you shu2e the cards and lay them face up on the table in four rows of seven cards, leaving a space of one card at the extreme left of each row. The following shows an example of initial layout. 

 

Next, you remove all cards of value 1, and put them in the open space at the left end of the rows: "11" to the top row, "21" to the next, and so on. 

Now you have 28 cards and four spaces, called gaps, in four rows and eight columns. You start moving cards from this layout. 

 

At each move, you choose one of the four gaps and fill it with the successor of the left neighbor of the gap. The successor of a card is the next card in the same suit, when it exists. For instance the successor of "42" is "43", and "27" has no successor. 

In the above layout, you can move "43" to the gap at the right of "42", or "36" to the gap at the right of "35". If you move "43", a new gap is generated to the right of "16". You cannot move any card to the right of a card of value 7, nor to the right of a gap. 

The goal of the game is, by choosing clever moves, to make four ascending sequences of the same suit, as follows. 

 

Your task is to find the minimum number of moves to reach the goal layout. 

输入:

The input starts with a line containing the number of initial layouts that follow. 

Each layout consists of five lines - a blank line and four lines which represent initial layouts of four rows. Each row has seven two-digit numbers which correspond to the cards. 

输出:

For each initial layout, produce a line with the minimum number of moves to reach the goal layout. Note that this number should not include the initial four moves of the cards of value 1. If there is no move sequence from the initial layout to the goal layout, produce "-1". 

样例:

分析:题意是把任一直接移到空格处为一步;

BFS加hash判重

简单来说hash就是把一个状态用一个数来标识,能一一对应最好(比方说康托展开),这样你就可以方便地知道这个状态有没有走过

  1 #include<iostream>
2 #include<sstream>
3 #include<cstdio>
4 #include<cstdlib>
5 #include<string>
6 #include<cstring>
7 #include<algorithm>
8 #include<functional>
9 #include<iomanip>
10 #include<numeric>
11 #include<cmath>
12 #include<queue>
13 #include<vector>
14 #include<set>
15 #include<cctype>
16 #define PI acos(-1.0)
17 const int INF = 0x3f3f3f3f;
18 const int NINF = -INF - 1;
19 typedef long long ll;
20 #define MOD 1000007
21 using namespace std;
22 ll Hash[MOD];
23 struct node
24 {
25 int maze[4][8];
26 int step;//记录步数
27 friend bool operator == (node a, node b)//重载结构体“==”
28 {
29 for (int i = 0; i < 4; ++i)
30 {
31 for (int j = 0; j < 8; ++j)
32 if (a.maze[i][j] != b.maze[i][j]) return false;
33 }
34 return true;
35 }
36 ll gethash()//获取hash值
37 {
38 ll value = 0;
39 for (int i = 0; i < 4; ++i)
40 {
41 for (int j = 0; j < 8; ++j)
42 value += (value<<ll(1)) + (ll)maze[i][j];//随意写
43 }
44 return value;
45 }
46 }st, ed;//起始与结束状态
47 bool verif(ll value)//hash判重函数
48 {
49 int num = value % MOD;//对大质数取余
50 while (Hash[num] != 0 && Hash[num] != value)//处理可能存在的hash冲突
51 {
52 num += 3;//随意写
53 num %= MOD;
54 }
55 if (Hash[num] == 0)
56 {
57 Hash[num] = value;
58 return true;
59 }
60 return false;
61 }
62 void bfs()
63 {
64 queue<node> q;
65 memset(Hash, 0, sizeof(Hash));
66 st.step = 0;
67 q.push(st);
68 verif(st.gethash());
69 while (q.size())
70 {
71 node tmp = q.front();
72 q.pop();
73 for (int i = 0; i < 4; ++i)
74 {
75 for (int j = 0; j < 8; ++j)
76 {
77 if (!tmp.maze[i][j])//寻找空格位置
78 {
79 node cur = tmp;
80 cur.step++;
81 int aim = tmp.maze[i][j - 1] + 1;
82 if (aim == 1 || aim == 8) continue;//空格前为空格或7则跳过
83 int x, y, flag = 0;
84 for (int m = 0; m < 4; ++m)
85 {
86 for (int n = 0; n < 8; ++n)
87 {
88 if (tmp.maze[m][n] == aim)
89 {
90 x = m, y = n;
91 flag = 1;
92 }
93 }
94 }
95 if (flag)
96 {
97 swap(cur.maze[x][y], cur.maze[i][j]);
98 ll value = cur.gethash();
99 //cout << value << endl;
100 if (verif(value))
101 {
102 if (cur == ed)
103 {
104 cout << cur.step << endl;
105 return;
106 }
107 q.push(cur);
108 }
109 }
110 }
111 }
112 }
113 }
114 cout << -1 << endl;
115 }
116 int main()
117 {
118 int T;
119 cin >> T;
120 for (int i = 0; i < 4; ++i)//结束时状态
121 {
122 ed.maze[i][7] = 0;
123 for (int j = 0; j < 7; ++j)
124 ed.maze[i][j] = (i + 1) * 10 + j + 1;
125 }
126 while (T--)
127 {
128 string nul;
129 getline(cin, nul);
130 for (int i = 0; i < 4; ++i)//直接输入时就解决个位数为1的移至行首操作
131 {
132 st.maze[i][0] = (i + 1) * 10 + 1;
133 for (int j = 1; j < 8; ++j)
134 {
135 cin >> st.maze[i][j];
136 if (st.maze[i][j] % 10 == 1) st.maze[i][j] = 0;
137 }
138 }
139 if (st == ed) cout << 0 << endl;
140 else bfs();
141 }
142 return 0;
143 }

HDU1067 Gap的更多相关文章

  1. DG gap sequence修复一例

    环境:Oracle 11.2.0.4 DG 故障现象: 客户在备库告警日志中发现GAP sequence提示信息: Mon Nov 21 09:53:29 2016 Media Recovery Wa ...

  2. 16 On Large-Batch Training for Deep Learning: Generalization Gap and Sharp Minima 1609.04836v1

    Nitish Shirish Keskar, Dheevatsa Mudigere, Jorge Nocedal, Mikhail Smelyanskiy, Ping Tak Peter Tang N ...

  3. 利用增量备份恢复因归档丢失造成的DG gap

    故障现象:data guard归档出现gap,悲剧的是丢失的归档在主库上被rman备份时删除了,丢失的归档大约有20几个,数据库大小约2T,如果重建DG将非常耗时间,因此决定利用增量备份的方式恢复DG ...

  4. (一)GATT Profile和GAP 简介(目前所有的BLE应用都基于GATT,所以也要了解是怎么一回事)-转发

    个人大总结:(先后顺序) 1.GAP协议定义多个角色(其中就有中心设备[GATT客户端](唯一)叫主设备||和外围设备[GATT服务端端](多个)也叫从设备). 2.先经过GAP协议,再有GATT协议 ...

  5. hdu.1067.Gap(bfs+hash)

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

  6. 【leetcode】Maximum Gap

    Maximum Gap Given an unsorted array, find the maximum difference between the successive elements in ...

  7. 【leetcode】Maximum Gap(hard)★

    Given an unsorted array, find the maximum difference between the successive elements in its sorted f ...

  8. Datagard產生gap

    本文轉載自無雙的小寶的博客:http://www.cnblogs.com/sopost/archive/2010/09/11/2190085.html 有時候因為網路或備份故障等原因,主機所產生的歸檔 ...

  9. [LintCode] Maximum Gap 求最大间距

    Given an unsorted array, find the maximum difference between the successive elements in its sorted f ...

随机推荐

  1. 【noi 2.6_7627】鸡蛋的硬度(DP)

    题意:其中n表示楼的高度,m表示你现在拥有的鸡蛋个数. 解法:f[i][j]表示 i 层楼有 j 个鸡蛋时,至少要扔多少次.3重循环,k为测试的楼层,分这时扔下去的鸡蛋碎和不碎的情况.要注意初始化. ...

  2. Educational Codeforces Round 89 (Rated for Div. 2) A. Shovels and Swords (贪心)

    题意:你有\(a\)个树枝和\(b\)个钻石,\(2\)个树枝和\(1\)个钻石能造一个铁铲,\(1\)个树枝和\(2\)个钻石能造一把剑,问最多能造多少铲子和剑. 题解:如果\(a\le b\),若 ...

  3. JavaScript——面向对象与原型

    在最外面使用this,此时this是window作用域下的,因此他指向全局变量 对象冒充: 实例属性不会共享!

  4. 01.原生态jdbc程序中问题总结

    1.数据库启动包配置到工程目录中(mysql5.1) mysql-connector-java-5.1.7-bin.jar 2.jdbc原生态操作数据库(程序) 操作mysql数据库 1 packag ...

  5. 力扣567.字符串的排列—C语言实现

    题目 来源:力扣(LeetCode)

  6. CentOS 6 修改/etc/security/limits.conf不生效办法

    我们使用CentOS系统,在部署新的服务经常会遇到 打开最大文件数限制 too many open files的警告,通常我们只需要修改/etc/security/limits.conf该文件,增加两 ...

  7. ansible的Ad-hoc命令

    本文主要介绍了ansible的Ad-hoc命令. Ansible提供两种方式去完成任务,一是 ad-hoc 命令,一是写 Ansible playbook.前者可以解决一些简单的任务, 后者解决较复杂 ...

  8. Redis 的缓存淘汰机制(Eviction)

    本文从源码层面分析了 redis 的缓存淘汰机制,并在文章末尾描述使用 Java 实现的思路,以供参考. 相关配置 为了适配用作缓存的场景,redis 支持缓存淘汰(eviction)并提供相应的了配 ...

  9. 关于rand()

    虽然很早就知道rand是伪随机了,但是一般都懒得用srand. 直到模拟银行家算法时不用srand就造成数据实在有点假(-_-||) 所以要记得srand((int)time(0))啊

  10. mysql(一)--mysql架构和执行流程

    1. 一条查询 SQL 语句是如何执行的? 我们的程序或者工具要操作数据库,第一步要做什么事情? 跟数据库建立连接.   1.1. 通信协议 首先,MySQL 必须要运行一个服务,监听默认的 3306 ...