题目连接

http://poj.org/problem?id=2046

Gap

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.

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.

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.

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

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

爆搜+哈希判重。。

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<set>
using std::set;
using std::pair;
using std::swap;
using std::queue;
using std::vector;
using std::multiset;
#define pb(e) push_back(e)
#define sz(c) (int)(c).size()
#define mp(a, b) make_pair(a, b)
#define all(c) (c).begin(), (c).end()
#define iter(c) __typeof((c).begin())
#define cls(arr, val) memset(arr, val, sizeof(arr))
#define cpresent(c, e) (find(all(c), (e)) != (c).end())
#define rep(i, n) for(int i = 0; i < (int)n; i++)
#define tr(c, i) for(iter(c) i = (c).begin(); i != (c).end(); ++i)
const int N = 1000007;
const int MOD = 100000007;
const int INF = 0x3f3f3f3f;
typedef long long ll;
struct Node {
int s;
int mat[4][8];
inline bool operator==(const Node &x) const {
rep(i, 4) {
rep(j, 8) {
if(mat[i][j] != x.mat[i][j]) return false;
}
}
return true;
}
inline int hash() const {
ll ret = 0, k = 1;
rep(i, 4) {
rep(j, 8) {
ret = (ret + k * mat[i][j]) % MOD;
k <<= 1;
}
}
return (int)ret;
}
inline void read() {
rep(i, 4) {
mat[i][0] = 0;
rep(j, 7) {
scanf("%d", &mat[i][j + 1]);
}
}
rep(i, 4) {
rep(j, 8) {
int v = mat[i][j];
if(1 == v % 10) {
swap(mat[i][j], mat[v / 10 -1][0]);
}
}
}
}
}start, goal;
struct Hash_Set {
int tot, A[N], head[N], next[N];
inline void init() {
tot = 0, cls(head, -1);
}
inline bool insert(const int val) {
int u = val % N;
for(int i = head[u]; ~i; i = next[i]) {
if(A[i] == val) return false;
}
A[tot] = val, next[tot] = head[u]; head[u] = tot++;
return true;
}
}hash;
void bfs() {
hash.init();
queue<Node> q;
q.push(start);
hash.insert(start.hash());
while(!q.empty()) {
Node x = q.front(); q.pop();
rep(i, 4) {
rep(j, 8) {
if(x.mat[i][j]) continue;
Node t = x;
int x1 = 0, y1 = 0, val = x.mat[i][j - 1] + 1;
if(1 == val || 8 == val % 10) continue;
rep(k, 4) {
rep(l, 8) {
if(val == x.mat[k][l]) {
x1 = k, y1 = l; k = 4;
break;
}
}
}
t.s = x.s + 1;
swap(t.mat[i][j], t.mat[x1][y1]);
if(t == goal) {
printf("%d\n", t.s);
return;
}
val = t.hash();
if(!hash.insert(val)) continue;
q.push(t);
}
}
}
puts("-1");
}
void solve() {
start.read();
rep(i, 4) {
rep(j, 7) {
goal.mat[i][j] = (i + 1) * 10 + (j + 1);
}
goal.mat[i][7] = 0;
}
if(start == goal) {
puts("0");
return;
}
bfs();
}
int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w+", stdout);
#endif
int t;
scanf("%d", &t);
while(t--) {
solve();
}
return 0;
}

poj 2046 Gap的更多相关文章

  1. POJ 2046 Gap 搜索- 状态压缩

    题目地址: http://poj.org/problem?id=2046 一道搜索状态压缩的题目,关键是怎样hash. AC代码: #include <iostream> #include ...

  2. poj 2046 Gap(bfs+hash)

    Description Let's play a card game called Gap. You have cards labeled with two-digit numbers. The fi ...

  3. poj 2046&&poj1961KMP 前缀数组

    Power Strings Time Limit: 3000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u Jav ...

  4. poj很好很有层次感(转)

    OJ上的一些水题(可用来练手和增加自信) (POJ 3299,POJ 2159,POJ 2739,POJ 1083,POJ 2262,POJ 1503,POJ 3006,POJ 2255,POJ 30 ...

  5. POJ题目分类推荐 (很好很有层次感)

    著名题单,最初来源不详.直接来源:http://blog.csdn.net/a1dark/article/details/11714009 OJ上的一些水题(可用来练手和增加自信) (POJ 3299 ...

  6. POJ 3518 Prime Gap(素数)

    POJ 3518 Prime Gap(素数) id=3518">http://poj.org/problem? id=3518 题意: 给你一个数.假设该数是素数就输出0. 否则输出比 ...

  7. POJ 3518 Prime Gap(素数题)

    [题意简述]:输入一个数,假设这个数是素数就输出0,假设不是素数就输出离它近期的两个素数的差值,叫做Prime Gap. [分析]:这题过得非常险.由于我是打的素数表. 由于最大的素数是1299709 ...

  8. poj 3518 Prime Gap

    Prime Gap Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7392   Accepted: 4291 Descrip ...

  9. poj 3469 最小割模板sap+gap+弧优化

    /*以核心1为源点,以核心2为汇点建图,跑一遍最大流*/ #include<stdio.h> #include<string.h> #include<queue> ...

随机推荐

  1. 【测试】DG的主切备,备切主

    1.首先要应用日志,保持主备库一致: 备库:SBDB@SYS> recover managed standby database using current logfile disconnect ...

  2. CI 自动提交表单

    //coontrol $this->load->view ( '/' . $this->index_lang ['FOLDER'] . '/eprepag_form.php', $p ...

  3. ios7 导航栏 手势 右划 自动返回 相关

    http://www.tuicool.com/articles/vMfAVv 纪录一下,

  4. 使用VAssistX给文件和函数添加注释-2015.12.31

    在Visual Studio使用VAssistX助手可以非常方便的给文件和函数添加注释,增加更多的记录信息,从而方便在时间久后,对代码阅读理解的提示,以及别人后续对代码的维护和BUG修改. 添加头文件 ...

  5. 深入了解Qt(二)之元对象系统(Meta-Object System)

    深入了解Qt主要内容来源于Inside Qt系列,本文做了部分删改,以便于理解.在此向原作者表示感谢! 在Qt Meta Object System-元对象系统这篇文章中,从底层实现的源码剖析了元对象 ...

  6. 五、用户数据报传输(UDP)

    1.UDP常用的发送和接收函数 int recvfrom(int sockfd,void *buf,int len,unsigned int flags,struct sockaddr *from,i ...

  7. JS常用的设计模式(11)—— 中介者模式

    中介者对象可以让各个对象之间不需要显示的相互引用,从而使其耦合松散,而且可以独立的改变它们之间的交互. 打个比方,军火买卖双方为了安全起见,找了一个信任的中介来进行交易.买家A把钱交给中介B,然后从中 ...

  8. Easyui扩展或者重载(方法和属性)

    1: 使用$.fn.datagrid.defaults.editors重载默认值. 每个编辑器都有以下方法: 名称 属性 描述 init container, options 初始化编辑器并返回目标对 ...

  9. 使chrome支持跨域访问

    在做后台开发的时候,使用了iframe框架.后台主页面如下: <div style="width:185px; overflow: hidden;" id="wes ...

  10. javaSE第十五天

    第十五天    117 1. 对象数组(掌握)    117 (1)定义:    117 (2)对象数组的内存图解    117 (3)案例:    117 2. 集合(Collection)(掌握) ...