HDU 1067 Gap

HDU 1067 Gap

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

 

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個標有兩位數的卡片。第一個數(14)表示卡片種類,第二個數(17)表示卡片的值。
首先,在桌上擺放四行七列的卡片,每行的最左邊留下一張卡片的空位。初始佈局以下:
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.ide


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

接着,把全部值爲1的卡片放到左側的空位: "11"在最上面,"21"在下一行,以此類推。
如今你有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.ui


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


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

每次移動,你須要選擇一個空位,放上空格左邊的後續卡。後繼卡是同一套牌中的下一張。例如"42"的後繼卡爲"43""27"沒有後繼卡。

上述佈局中,你能夠移動"43""42"右邊的空位,或者移動"36""35"右邊。若你移動"43",則有一個新的空位出如今"16"右邊。不能移動任何卡片到值爲7的卡片右邊,也不能移動到空位的右邊。

遊戲的目標是使用明智移動得出以下四個上升系列。
CN

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

你的目標是找出達成目標佈局的最小移動數。
CN

 

Input - 輸入orm

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

輸入起始行的數字表示初始佈局的數量。
每一個佈局五行 - 一行空,四行初始佈局。每行有七個對應卡片的兩位數。
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++

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <map>
 5 #include <queue>
 6 #define MX 32
 7 #define INF 0x7F7F7F7F
 8 #define LL long long
 9 #define mod 1000007
10 struct Ary {
11     int a[MX], s;
12 }now, nxt;
13 int hash[mod], opt, ed[MX] = { 11, 12, 13, 14, 15, 16, 17, 0, 21, 22, 23, 24, 25, 26, 27, 0, 31, 32, 33, 34, 35, 36, 37, 0, 41, 42, 43, 44, 45, 46, 47 };
14 int getHash_i() {
15     LL i, j = 1, rtn;
16     for (i = rtn = 0; i < MX; ++i) {
17         rtn ^= (j*nxt.a[i]) ^ ed[i];
18         j = (j << 1) % mod;
19     }
20     return rtn%mod;
21 }
22 int getHash_v() {
23     LL i, j = 1, rtn;
24     for (i = rtn = 0; i < MX; ++i) {
25         rtn ^= j*(nxt.a[i] ^ ed[i]);
26         j = (j << 1) % mod;
27     }
28     return rtn%mod;
29 }
30 bool setHash() {
31     for (int i = getHash_i(), v = getHash_v(); i < mod; ++i) {
32         if (~hash[i]) {
33             if (hash[i] == v) return 0;
34         }
35         else { hash[i] = v; return 1; }
36     }
37     return 0;
38 }
39 void BFS() {
40     int idx[48], zro[4], iz, i, j;
41     hash[getHash_i()] = getHash_v();
42     std::queue<Ary> q; q.push(nxt);
43     while (!q.empty()) {
44         now = q.front(); q.pop();
45         if (now.s >= opt) continue;
46         if (memcmp(now.a, ed, sizeof ed) == 0) {
47             opt = std::min(opt, now.s);
48             continue;
49         }
50         ++now.s;
51         for (i = iz = 0; i < MX; ++i) {
52             (now.a[i] ? idx[now.a[i]] : zro[iz++]) = i;
53         }
54         for (i = 0; i < 4; ++i) {
55             j = zro[i];
56             if (now.a[j - 1] % 10 == 7 || !now.a[j - 1]) continue;
57             nxt = now;
58             nxt.a[j] = now.a[j - 1] + 1;
59             nxt.a[idx[nxt.a[j]]] = 0;
60             if (setHash()) q.push(nxt);
61         }
62     }
63 }
64 int main() {
65     int t, i, j;
66     scanf("%d", &t);
67     while (t--) {
68         memset(hash, -1, sizeof hash); opt = INF;
69         for (i = nxt.s = 0, j = 1; i < MX; ++i) {
70             if (i % 8) {
71                 scanf("%d", nxt.a + i);
72                 if (nxt.a[i] % 10 == 1) nxt.a[i] = 0;
73                 continue;
74             }
75             nxt.a[i] = (j += 10);
76         }
77         BFS();
78         printf("%d\n", opt == INF ? -1 : opt);
79     }
80     return 0;
81 }
相關文章
相關標籤/搜索