HDU1067 Gap

原创 2015年11月18日 21:12:46

Gap

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 810    Accepted Submission(s): 441


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.



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
 

Source
 

Recommend
JGShining
 




题意比较复杂,,,总之就是初始输入从第二列开始输入,然后把尾数是1的放到第一列,随后可以在空位放入空位左面那个数+1,表格中对应的那个数位置为空,因此如果尾数为7就无法移动。最终状态是规整的11到47,问最少要多少步,如果不可能就输出-1。

这题作为搜索本身很简单,就是在判重的时候需要建立hash表。建立的hash函数包含了表格中所有元素,所以不会有冲突。

#include <iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#define N 1123451
using namespace std;

struct node {
    int g[4][8];
    int step;
}tn;
int vis[N];
int gethash(node &t)
{
    int ans=0;
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<8;j++)
        {
            ans=ans*7+t.g[i][j]%10;
            ans=ans*7+t.g[i][j]/10;
        }
    }
    return (ans&0x7fffffff)%N;
}

bool judge (node a)
{
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<7;j++)
        {
            if(a.g[i][j]!=(i+1)*10+j+1)
                return false;
        }
    }
    return true;
}

void change(node &t,int num)
{
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<8;j++)
        {
            if(t.g[i][j]==num+1)
            {
                t.g[i][j]=0;
                return ;
            }
        }
    }
}

int bfs()
{
    queue <node> q;
    node buf,next;
    int t;
    tn.step=0;
    memset(vis,0,sizeof(vis));
    for(int i=0;i<4;i++)
    {
        tn.g[i][0]=(i+1)*10+1;
    }
    vis[gethash(tn)]=1;
    q.push(tn);
    while(!q.empty())
    {
        buf=q.front();q.pop();
        if(judge(buf))
            return buf.step;
        for(int i=0;i<4;i++)
            for(int j=0;j<8;j++)
            {
                if(buf.g[i][j]==0&&buf.g[i][j-1]!=0&&buf.g[i][j-1]%10!=7)
                {
                    next=buf;next.step++;
                    change(next,next.g[i][j-1]);
                    next.g[i][j]=next.g[i][j-1]+1;
                    t=gethash(next);
                    if(!vis[t])
                    {
                        vis[t]=1;
                        q.push(next);
                    }
                }
            }
    }
    return -1;
}

int main()
{
    int K;
    cin>>K;
    while(K--)
    {
        for(int i=0;i<4;i++)
        {
            for(int j=1;j<8;j++)
            {
                scanf("%d",&tn.g[i][j]);
                if(tn.g[i][j]%10==1) tn.g[i][j]=0;
            }
        }
        printf("%d\n",bfs());
    }
}

HDU 1067 Gap(哈希+bfs)

Gap Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm...
  • Yasola
  • Yasola
  • 2016年07月24日 14:52
  • 277

hdu1067 N - Gap

Home Problems Status Contest [ak1] Logout WUST ACM CLUB SUMMER TRAINING (3) 277:06:36 307:00:00...

hdu1067 Gap (bfs+hash)

题意:给定一个4*8的矩阵,最左边一列是空的,右边4*7的格子被11~17,21~27,31~37,41~47这28个数字填满。 首先把11,21,31,41移动到最左边一列,然后每次找一个空格,把...

hdu 1067 Gap bfs+hash

t #include #include #include #include #include using namespace std; struct Node{ int m...

HDU1067 Gap 【BFS+MAP】

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

hdu 1067 Gap

本来认为是个数学题或者dp题,但是后来看到规则发现用搜索完全可以做     因为规则限制,每次只能把空白左边下一位的数移动到空白处,所以每次最多走4种情况,这就可以bfs了     一开始用map...

HDU1067 Gap( BFS+ HASH 剪枝,矩阵用一个数表示)

题意:在4*8 的图中,给你4种类型的牌,每种牌序号1-7,比如42表示第4种牌的第二张,现在给你4*7一共28张,同时最左边的一列开始空的,第一步你要做的是把每种类型的1号牌从上到下放在这列空的位置...

hdu3549 SAP+GAP

超级久没打过网络流了,感觉要完(van)。。 于是找了个练手的题目来搞一波,决定最近做几道题目巩固一波。 (%%%hzwer网络流24题) 题意很简单,就是模板来着的。。原本我不准备写SAP的讲...

POJ 1067 HDU 1527 取石子游戏(威佐夫博奕)

取石子游戏、威佐夫博奕、betty贝蒂定理、胜态、负态、状态转移、覆盖(分划)、高斯函数、第二数学归纳法、黄金分割比例...

[威佐夫博弈 黄金分割比 数学技巧] POJ 1067 取石子游戏 & HDU 1527 取石子游戏

论文:杨思雨--美,无处不在——浅谈“黄金分割”和信息学的联系 以下摘录证明 #include #include #include #inc...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HDU1067 Gap
举报原因:
原因补充:

(最多只允许输入30个字)