Gap bfs()+hash判重

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
***************************************************************************************************************************
  1 #include<iostream>
  2 #include<string>
  3 #include<cstring>
  4 #include<cmath>
  5 #include<queue>
  6 #include<cstdio>
  7 using namespace std;
  8 #define  LL  __int64
  9 #define maxn  1000000+7
 10 LL  hash[maxn];
 11 LL  bin[34];
 12 LL endval,n,m,flag;
 13 int ans,cas;
 14 int tmp[4][8];
 15 int i,j,k;
 16 int  faval[4][8]=
 17 {
 18  11,12,13,14,15,16,17,0,
 19  21,22,23,24,25,26,27,0,
 20  31,32,33,34,35,36,37,0,
 21  41,42,43,44,45,46,47,0
 22 };
 23 struct node
 24 {
 25     LL val;
 26     int mp[4][8];
 27     int cnt;
 28     int blankx[4],blanky[4];
 29 }cur,now;
 30 queue<node>Q;
 31 
 32 void premap()//第一步操作都相同
 33 {
 34     int it,jt;
 35     for(it=0;it<4;it++)
 36      for(jt=1;jt<8;jt++)
 37      {
 38        if(cur.mp[it][jt]==11)
 39        {
 40            swap(cur.mp[it][jt],cur.mp[0][0]);
 41            cur.blankx[0]=it;
 42            cur.blanky[0]=jt;
 43        }
 44        else if(cur.mp[it][jt]==21)
 45        {
 46            swap(cur.mp[it][jt],cur.mp[1][0]);
 47            cur.blankx[1]=it;
 48            cur.blanky[1]=jt;
 49        }
 50        else if(cur.mp[it][jt]==31)
 51        {
 52            swap(cur.mp[it][jt],cur.mp[2][0]);
 53            cur.blankx[2]=it;
 54            cur.blanky[2]=jt;
 55        }
 56        else if(cur.mp[it][jt]==41)
 57        {
 58            swap(cur.mp[it][jt],cur.mp[3][0]);
 59            cur.blankx[3]=it;
 60            cur.blanky[3]=jt;
 61        }
 62 
 63      }
 64 }
 65 
 66 bool Is_can()//判断状态是否符合结果
 67 {
 68     int it,jt;
 69     LL s=0;
 70     for(it=0;it<4;it++)
 71      for(jt=0;jt<8;jt++)
 72      {
 73        s+=cur.mp[it][jt]*bin[it*8+jt];
 74      }
 75      if(s==endval)return true;
 76      return false;
 77 }
 78 
 79 bool hash_add()//hash判重
 80 {
 81     int it,jt;
 82     if(Is_can())flag=1;
 83     int ss=(int)(cur.val%maxn);
 84     while(hash[ss]!=-1&&hash[ss]!=cur.val)
 85     {
 86         ss+=10;
 87         if(ss>=maxn)
 88            ss=ss%maxn;
 89     }
 90     if(hash[ss]==-1)
 91     {
 92         hash[ss]=cur.val;
 93         return true;
 94     }
 95     return false;
 96 }
 97 
 98 bool bfs()//bfs()判断最符合的状态
 99 {
100     int it,jt,kt;
101     LL tval;
102     while(!Q.empty())
103      Q.pop();
104     Q.push(cur);
105     while(!Q.empty())
106     {
107         now=Q.front();
108         Q.pop();
109         for(kt=0;kt<4;kt++)
110         {
111             int xx=now.blankx[kt];
112             int yy=now.blanky[kt];
113             memcpy(tmp,now.mp,sizeof(now.mp));
114             for(it=0;it<4;it++)
115              for(jt=0;jt<8;jt++)
116              {
117                  if(tmp[it][jt]==0)continue;
118                 if(tmp[xx][yy-1]+1==tmp[it][jt])
119                 {
120                     tval=now.val;
121                     tval-=tmp[it][jt]*bin[it*8+jt];
122                     tval+=tmp[it][jt]*bin[xx*8+yy];
123                     swap(tmp[xx][yy],tmp[it][jt]);
124                     cur.val=tval;
125                     memcpy(cur.mp,tmp,sizeof(tmp));
126                     if(hash_add())
127                     {
128                         if(flag)
129                         {
130                             ans=now.cnt+1;
131                             return true;
132                         }
133                         memcpy(cur.blankx,now.blankx,sizeof(cur.blankx));
134                         memcpy(cur.blanky,now.blanky,sizeof(cur.blanky));
135                         cur.cnt=now.cnt+1;
136                         cur.blankx[kt]=it;
137                         cur.blanky[kt]=jt;
138                         Q.push(cur);
139                     }
140                 }
141              }
142 
143         }
144     }
145     return false;
146 }
147 
148 int main()
149 {
150     bin[0]=1;
151     for(i=1;i<=33;i++)
152      bin[i]=bin[i-1]<<1;
153      endval=0;
154     for(i=0;i<4;i++)
155      for(j=0;j<8;j++)
156       endval+=faval[i][j]*bin[i*8+j];
157     //cout<<"endval:: "<<endval<<endl;
158     scanf("%d",&cas);
159     while(cas--)
160     {
161       flag=0;
162       LL s=0;
163       memset(hash,-1,sizeof(hash));
164       for(i=0;i<4;i++)
165       {
166           cur.blankx[i]=i;
167           cur.blanky[i]=0;
168           cur.mp[i][0]=0;
169           for(j=1;j<8;j++)
170           {
171               scanf("%d",&cur.mp[i][j]);
172               s+=cur.mp[i][j]*bin[i*8+j];
173           }
174       }
175       cur.val=s;
176       cur.cnt=0;
177       premap();
178       hash_add();
179       if(flag)
180     printf("0\n");
181       else
182        {
183          if(bfs())
184            printf("%d\n",ans);
185          else
186            printf("-1\n");
187        }
188     }
189     return 0;
190 
191 }
View Code

 

转载于:https://www.cnblogs.com/sdau--codeants/p/3426711.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值