HDU 1067 Gap

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

 

Problem Description - 题目描述

  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.
让我们玩个叫Gap的游戏。
你有28个标有两位数的卡片。第一个数( ~ )表示卡片种类,第二个数(~)表示卡片的值。
首先,在桌上摆放四行七列的卡片,每行的最左边留下一张卡片的空位。初始布局如下:

CN

  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.

接着,把所有值为1的卡片放到左侧的空位: ""在最上面,""在下一行,以此类推。
现在你有28张卡片与4个空位,共四行八列,并需要从这个布局开始移动卡片。

CN

  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.

每次移动,你需要选择一个空位,放上空格左边的后续卡。后继卡是同一套牌中的下一张。例如""的后继卡为"",""没有后继卡。

上述布局中,你可以移动""至""右边的空位,或者移动""至""右边。若你移动"",则有一个新的空位出现在""右边。不能移动任何卡片到值为7的卡片右边,也不能移动到空位的右边。

游戏的目标是使用明智移动得出如下四个上升系列。

CN

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

你的目标是找出达成目标布局的最小移动数。

CN

Input - 输入

  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.

输入起始行的数字表示初始布局的数量。
每个布局五行 - 一行空,四行初始布局。每行有七个对应卡片的两位数。

CN

Output - 输出

  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".

对于每个初始布局,输出一行达成目标布局的最小移动数。注意,这个数不包括值为1卡片的四次初始化移动。如果不存在从初始至目标布局的移动序列,则输出"-1"。

CN

Sample Input - 输入样例

4

12 13 14 15 16 17 21
22 23 24 25 26 27 31
32 33 34 35 36 37 41
42 43 44 45 46 47 11 26 31 13 44 21 24 42
17 45 23 25 41 36 11
46 34 14 12 37 32 47
16 43 27 35 22 33 15 17 12 16 13 15 14 11
27 22 26 23 25 24 21
37 32 36 33 35 34 31
47 42 46 43 45 44 41 27 14 22 35 32 46 33
13 17 36 24 44 21 15
43 16 45 47 23 11 26
25 37 41 34 42 12 31

Sample Output - 输出样例

0
33
60
-1

题解

  BFS + 哈希。

  之前作死想用map来个暴力判重先试试水,结果不但速度慢,内存直接炸了。

  然后灵(脑)一光(子)一闪(抽),一个哈希数组坐标,一个哈希数字值,目测出问题的概率不大,A了之后就懒得改了。

代码 C++

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
#define MX 32
#define INF 0x7F7F7F7F
#define LL long long
#define mod 1000007
struct Ary {
int a[MX], s;
}now, nxt;
int hash[mod], opt, ed[MX] = { , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , };
int getHash_i() {
LL i, j = , rtn;
for (i = rtn = ; i < MX; ++i) {
rtn ^= (j*nxt.a[i]) ^ ed[i];
j = (j << ) % mod;
}
return rtn%mod;
}
int getHash_v() {
LL i, j = , rtn;
for (i = rtn = ; i < MX; ++i) {
rtn ^= j*(nxt.a[i] ^ ed[i]);
j = (j << ) % mod;
}
return rtn%mod;
}
bool setHash() {
for (int i = getHash_i(), v = getHash_v(); i < mod; ++i) {
if (~hash[i]) {
if (hash[i] == v) return ;
}
else { hash[i] = v; return ; }
}
return ;
}
void BFS() {
int idx[], zro[], iz, i, j;
hash[getHash_i()] = getHash_v();
std::queue<Ary> q; q.push(nxt);
while (!q.empty()) {
now = q.front(); q.pop();
if (now.s >= opt) continue;
if (memcmp(now.a, ed, sizeof ed) == ) {
opt = std::min(opt, now.s);
continue;
}
++now.s;
for (i = iz = ; i < MX; ++i) {
(now.a[i] ? idx[now.a[i]] : zro[iz++]) = i;
}
for (i = ; i < ; ++i) {
j = zro[i];
if (now.a[j - ] % == || !now.a[j - ]) continue;
nxt = now;
nxt.a[j] = now.a[j - ] + ;
nxt.a[idx[nxt.a[j]]] = ;
if (setHash()) q.push(nxt);
}
}
}
int main() {
int t, i, j;
scanf("%d", &t);
while (t--) {
memset(hash, -, sizeof hash); opt = INF;
for (i = nxt.s = , j = ; i < MX; ++i) {
if (i % ) {
scanf("%d", nxt.a + i);
if (nxt.a[i] % == ) nxt.a[i] = ;
continue;
}
nxt.a[i] = (j += );
}
BFS();
printf("%d\n", opt == INF ? - : opt);
}
return ;
}

HDU 1067 Gap的更多相关文章

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

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

  2. HDU - 1067 Gap (bfs + hash) [kuangbin带你飞]专题二

    题意:    起初定28张卡牌的排列,把其中11,  21, 31, 41移动到第一列,然后就出现四个空白,每个空白可以用它的前面一个数的下一个数填充,例如43后面的空格可以用44填充,但是47后面即 ...

  3. 【hdu 1067】Gap

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

  4. [hdu 1067]bfs+hash

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1067 queue里面果然不能放vector,还是自己写的struct比较省内存…… #include& ...

  5. BFS+Hash(储存,判重) HDOJ 1067 Gap

    题目传送门 题意:一个图按照变成指定的图,问最少操作步数 分析:状态转移简单,主要是在图的存储以及判重问题,原来队列里装二维数组内存也可以,判重用神奇的hash技术 #include <bits ...

  6. KUANGBIN带你飞

    KUANGBIN带你飞 全专题整理 https://www.cnblogs.com/slzk/articles/7402292.html 专题一 简单搜索 POJ 1321 棋盘问题    //201 ...

  7. [kuangbin带你飞]专题1-23题目清单总结

    [kuangbin带你飞]专题1-23 专题一 简单搜索 POJ 1321 棋盘问题POJ 2251 Dungeon MasterPOJ 3278 Catch That CowPOJ 3279 Fli ...

  8. ACM--[kuangbin带你飞]--专题1-23

    专题一 简单搜索 POJ 1321 棋盘问题POJ 2251 Dungeon MasterPOJ 3278 Catch That CowPOJ 3279 FliptilePOJ 1426 Find T ...

  9. HDU 5643 King's Game 打表

    King's Game 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5643 Description In order to remember hi ...

随机推荐

  1. Pycharm 自定义文件模板

    Pycharm 自定义文件模板 每次新建文件都有相同的代码框架,每次重复敲浪费了程序员的寿命啊 按照下面方式自定义自己的模板:

  2. 《图解HTTP》读书笔记(七:通信数据转发程序-代理/网关/隧道)

    HTTP通信时,除客户端和服务器以外,还有一些用于通信数据转发的应用程序,例如代理.网关和隧道,它们可以配合服务器工作.这些服务器和应用程序可以将请求转发给通信线路上的下一站服务器,并且能接收从那台服 ...

  3. ASM

    一. 磁盘阵列 RAID 5 二. STRRPE 三. LAT 四. [root@localhost ~]# fdisk /dev/sdjDevice contains neither a valid ...

  4. JavaWeb学习之三层架构实例(二)

    引言 这个实例是上一个实例JavaWeb学习 三层架构实例(一)的加强版,实现的是在前端对数据库中student表的 增.删.改.查 操作.关于三层组成云云,这里就不再叙述. 实例 效果图 先来看一下 ...

  5. JMeter-正则表达式(HTML)

    2019-04-26问题:需要取出交易成功,但是有黄色部分 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN& ...

  6. 如何增加Ubuntu交换空间swap

    如何增加Ubuntu交换空间swap 1  使用命令查看系统内swap分区大小 green@green:~$ free -m total used free shared buff/cache ava ...

  7. 用html5实现音频播放器

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  8. spark的运行模式

    1.local(本地模式) 单机模式,通常用来测试 将spark应用以多线程方式,直接运行在本地 本地模式可以启动多个executor不过上限不能超过cpu数 2.standalone(独立模式) 独 ...

  9. Django框架详细介绍---Form表单

    一.概述 在HTML页面中,利用form表单向后端提交数据时,需要编写input等输入标签并用form标签包裹起来,与此同时,在很多应用场景之下需要对用户输入的数据校验,例如注册登录页面中,校验用户注 ...

  10. SQL 连接(内连接,外连接)

    内连接 现在有两张表,学生表student1,成绩表SC1,两张表的数据如下 现在要对两张表做连接查询,连接一般需要写条件,where 或者 on 后面 , select * from student ...