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.
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
百度翻译:让我们玩一个叫盖普的纸牌游戏。你有28张卡片,上面有两个数字。第一个数字(从1到4)表示卡的大小写,第二个数字(从1到7)表示卡的值。首先,你将卡片分为四行七张,面朝上放在桌子上,在每行最左边留出一张卡片的
空间。以下是初始布局的示例。接下来,移除所有值为1的卡,并将它们放在行左端的空白处:“11”到最上面一行,“21”到下一行,依此类推。现在您有28张卡片和四个空格,称为间隙,分为四行八列。从这个布局开始移动卡片。在每一个
移动中,您选择四个间隙中的一个,并用间隙左邻居的继承者填充它。当一张卡存在时,它的后继卡就是同一套中的下一张卡。例如,“42”的继承人是“43”,“27”没有继承人。在上述布局中,您可以将“43”移动到“42”右侧的间隙,或将
“36”移动到“35”右侧的间隙。如果移动“43”,将在“16”的右侧生成新的间隙。您不能将任何卡移到值为7的卡的右侧,也不能移到间隙的右侧。游戏的目标是,通过选择巧妙的动作,使同一套衣服的四个升序,如下所示。您的任务是找到达
到目标布局的最少移动次数。
思路:将表格转换成字符串,用map对走过的字符串标记,然后广搜就行。
1 #include <cstdio> 2 #include <fstream> 3 #include <algorithm> 4 #include <cmath> 5 #include <deque> 6 #include <vector> 7 #include <queue> 8 #include <string> 9 #include <cstring> 10 #include <map> 11 #include <stack> 12 #include <set> 13 #include <sstream> 14 #include <iostream> 15 #define mod 1000000007 16 #define ll long long 17 using namespace std; 18 19 //最终的结果 20 char jg[]={11,12,13,14,15,16,17,1, 21 21,22,23,24,25,26,27,1, 22 31,32,33,34,35,36,37,1, 23 41,42,43,44,45,46,47,1,0}; 24 struct node 25 { 26 char ch[35];//方格 27 int t;//步数 28 }; 29 char tu[35];//初始方格 30 int n,ans; 31 void bfs() 32 { 33 queue<node> qu; 34 node no,s; 35 strcpy(no.ch,tu);//将初始方格复制到结构体中 36 no.t=0; 37 qu.push(no); 38 map<string,int> ma;//对每个方格进行标记 39 int bj=1; 40 ma[tu]=bj++;//采用不同的数进行标记,方便判断得到结果时结束搜索 41 if(ma[tu]==ma[jg])//判断初始方格是否是最终的结果 42 { 43 ans=0; 44 return ; 45 } 46 ma[jg]=bj++;//对结果进行标记 47 while(!qu.empty()) 48 { 49 no=qu.front(); 50 qu.pop(); 51 for(int i=0;i<32;i++)//总共32个方格 52 { 53 if(no.ch[i]==1&&no.ch[i-1]!=1&&no.ch[i-1]%10!=7)//当这个方格是空格时,并且前面不是7和1 54 { 55 s=no; 56 int j=0; 57 while(1)//找出应该与该方格交换数值的位置 58 { 59 if(s.ch[j]==s.ch[i-1]+1) 60 { 61 s.ch[j]=1; 62 break; 63 } 64 j++; 65 } 66 s.ch[i]=s.ch[i-1]+1; 67 s.t++; 68 if(ma[s.ch]==ma[jg])//到达最终结果,结束循环 69 { 70 ans=s.t; 71 return ; 72 } 73 if(ma[s.ch]==0)//如果没走过,就入队,并标记 74 { 75 ma[s.ch]=bj++; 76 qu.push(s); 77 } 78 } 79 } 80 } 81 ans=-1; 82 } 83 int main() 84 { 85 scanf("%d",&n); 86 while(n--) 87 { 88 int s; 89 ans=0; 90 for(int i=0;i<4;i++) 91 { 92 for(int j=1;j<8;j++) 93 { 94 scanf("%d",&s); 95 if(s%10==1) 96 { 97 tu[(s/10-1)*8]=s;//将第一列排好 98 tu[i*8+j]=1; 99 } 100 else 101 { 102 tu[i*8+j]=s; 103 } 104 } 105 } 106 bfs(); 107 printf("%d ",ans); 108 } 109 }