UESTC 魔法少女小蟹

转自http://www.cnblogs.com/whatbeg/p/3728557.html

直接BFS肯定不行,复杂度太高。

先不考虑加加减操作,因为它们不涉及以为,很好处理。

因为一开始魔棒是在最左端,所以第i个位置被访问过了,则前面的一定都访问过。同时,我们可以直接通过和最后一位交换的方式访问最后一位。所以所有被访问的状态(标号)就只有1、12、123、1234、12345、123456、16、126、1236、12346,就10个。

所以状态记录就是dis[6][6][6][6][6][6][6][10],前6个6 代表现在的第i位是原来的第j位,第7个6 代表魔杖现在在哪,10 代表有哪些位置被访问过了。

dis表示到当前状态的步数(最小)。

BFS出来后,枚举6位数的每一位和指针位置和10种状态,看此状态是否已访问,如果已访问,表示能够到达这个状态,然后看从这个状态到目标状态还需多少步(有可能达不到),然后看dis[状态]+步数是否小于最小步数,是则更新答案。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <algorithm>
  6 #include <queue>
  7 #define Mod 1000000007
  8 #define INT 2147483647
  9 using namespace std;
 10 #define N 50007
 11 
 12 struct node
 13 {
 14     int p[7];
 15     int point,state;
 16     int step;
 17 }S;
 18 
 19 void Popy(int *p1,int *p2)
 20 {
 21     for(int i=1;i<7;i++)
 22         p1[i] = p2[i];
 23 }
 24 
 25 int dis[7][7][7][7][7][7][7][10];
 26 int E[7],SS[7];
 27 
 28 int min(int ka,int kb)
 29 {
 30     if(ka < kb)
 31         return ka;
 32     return kb;
 33 }
 34 
 35 int max(int ka,int kb)
 36 {
 37     if(ka > kb)
 38         return ka;
 39     return kb;
 40 }
 41 
 42 void BFS(node S)
 43 {
 44     queue<node> que;
 45     memset(dis,-1,sizeof(dis));
 46     que.push(S);
 47     dis[S.p[1]][S.p[2]][S.p[3]][S.p[4]][S.p[5]][S.p[6]][1][0] = 0;
 48     while(!que.empty())
 49     {
 50         node tmp = que.front();
 51         que.pop();
 52         for(int i=0;i<4;i++)
 53         {
 54             node now;
 55             if(i == 0)   //与左边交换
 56             {
 57                 swap(tmp.p[1],tmp.p[tmp.point]);
 58                 Popy(now.p,tmp.p);
 59                 swap(tmp.p[1],tmp.p[tmp.point]);
 60                 now.point = tmp.point;
 61                 now.state = tmp.state;
 62                 now.step = tmp.step + 1;
 63                 if(dis[now.p[1]][now.p[2]][now.p[3]][now.p[4]][now.p[5]][now.p[6]][now.point][now.state] == -1 || (dis[now.p[1]][now.p[2]][now.p[3]][now.p[4]][now.p[5]][now.p[6]][now.point][now.state] != -1 && now.step < dis[now.p[1]][now.p[2]][now.p[3]][now.p[4]][now.p[5]][now.p[6]][now.point][now.state]))
 64                 {
 65                     dis[now.p[1]][now.p[2]][now.p[3]][now.p[4]][now.p[5]][now.p[6]][now.point][now.state] = now.step;
 66                     que.push(now);
 67                 }
 68             }
 69             else if(i == 1)   //与右边交换
 70             {
 71                 swap(tmp.p[6],tmp.p[tmp.point]);
 72                 Popy(now.p,tmp.p);
 73                 swap(tmp.p[6],tmp.p[tmp.point]);
 74                 now.point = tmp.point;
 75                 if(tmp.state <= 3)
 76                     now.state = tmp.state + 6;
 77                 else if(tmp.state == 4)
 78                     now.state = tmp.state + 1;
 79                 else
 80                     now.state = tmp.state;
 81                 now.step = tmp.step + 1;
 82                 if(dis[now.p[1]][now.p[2]][now.p[3]][now.p[4]][now.p[5]][now.p[6]][now.point][now.state] == -1 || (dis[now.p[1]][now.p[2]][now.p[3]][now.p[4]][now.p[5]][now.p[6]][now.point][now.state] != -1 && now.step < dis[now.p[1]][now.p[2]][now.p[3]][now.p[4]][now.p[5]][now.p[6]][now.point][now.state]))
 83                 {
 84                     dis[now.p[1]][now.p[2]][now.p[3]][now.p[4]][now.p[5]][now.p[6]][now.point][now.state] = now.step;
 85                     que.push(now);
 86                 }
 87             }
 88             else if(i == 2)   //左移
 89             {
 90                 Popy(now.p,tmp.p);
 91                 now.point = max(1,tmp.point-1);
 92                 now.state = tmp.state;
 93                 now.step = tmp.step + 1;
 94                 if(dis[now.p[1]][now.p[2]][now.p[3]][now.p[4]][now.p[5]][now.p[6]][now.point][now.state] == -1 || (dis[now.p[1]][now.p[2]][now.p[3]][now.p[4]][now.p[5]][now.p[6]][now.point][now.state] != -1 && now.step < dis[now.p[1]][now.p[2]][now.p[3]][now.p[4]][now.p[5]][now.p[6]][now.point][now.state]))
 95                 {
 96                     dis[now.p[1]][now.p[2]][now.p[3]][now.p[4]][now.p[5]][now.p[6]][now.point][now.state] = now.step;
 97                     que.push(now);
 98                 }
 99             }
100             else if(i == 3)  //右移
101             {
102                 Popy(now.p,tmp.p);
103                 now.point = min(6,tmp.point+1);
104                 if(tmp.state < 5)
105                     now.state = tmp.state+1;
106                 else if(tmp.state == 5)
107                     now.state = tmp.state;
108                 else if(tmp.state < 9)
109                     now.state = tmp.state+1;
110                 else
111                     now.state = tmp.state-4;
112                 now.step = tmp.step + 1;
113                 if(dis[now.p[1]][now.p[2]][now.p[3]][now.p[4]][now.p[5]][now.p[6]][now.point][now.state] == -1 || (dis[now.p[1]][now.p[2]][now.p[3]][now.p[4]][now.p[5]][now.p[6]][now.point][now.state] != -1 && now.step < dis[now.p[1]][now.p[2]][now.p[3]][now.p[4]][now.p[5]][now.p[6]][now.point][now.state]))
114                 {
115                     dis[now.p[1]][now.p[2]][now.p[3]][now.p[4]][now.p[5]][now.p[6]][now.point][now.state] = now.step;
116                     que.push(now);
117                 }
118             }
119         }
120     }
121 }
122 
123 int main()
124 {
125     int a,b,i;
126     int h[7];
127     int pot,status;
128     while(scanf("%d%d",&a,&b)!=EOF)
129     {
130         S.p[1] = 1;   //标号。初始都在自己的位置
131         S.p[2] = 2;
132         S.p[3] = 3;
133         S.p[4] = 4;
134         S.p[5] = 5;
135         S.p[6] = 6;
136         S.point = 1;
137         S.state = 0;
138         S.step = 0;
139         SS[1] = (a/100000)%10;
140         SS[2] = (a/10000)%10;
141         SS[3] = (a/1000)%10;
142         SS[4] = (a/100)%10;
143         SS[5] = (a/10)%10;
144         SS[6] = a%10;
145         E[1] = (b/100000)%10;
146         E[2] = (b/10000)%10;
147         E[3] = (b/1000)%10;
148         E[4] = (b/100)%10;
149         E[5] = (b/10)%10;
150         E[6] = b%10;
151         BFS(S);
152         int ans = Mod;
153         for(h[1]=1;h[1]<=6;h[1]++)
154         {
155             for(h[2]=1;h[2]<=6;h[2]++)
156             {
157                 if(h[2] != h[1])
158                 {
159                     for(h[3]=1;h[3]<=6;h[3]++)
160                     {
161                         if(h[3] != h[2] && h[3] != h[1])
162                         {
163                             for(h[4]=1;h[4]<=6;h[4]++)
164                             {
165                                 if(h[4] != h[1] && h[4] != h[2] && h[4] != h[3])
166                                 {
167                                     for(h[5]=1;h[5]<=6;h[5]++)
168                                     {
169                                         if(h[5] != h[1] && h[5] != h[2] && h[5] != h[3] && h[5] != h[4])
170                                         {
171                                             for(h[6]=1;h[6]<=6;h[6]++)
172                                             {
173                                                 if(h[6] != h[1] && h[6] != h[2] && h[6] != h[3] && h[6] != h[4] && h[6] != h[5])
174                                                 {
175                                                     for(pot=1;pot<=6;pot++)
176                                                     {
177                                                         for(status=0;status<10;status++)
178                                                         {
179                                                             if(dis[h[1]][h[2]][h[3]][h[4]][h[5]][h[6]][pot][status] != -1)
180                                                             {
181                                                                 int cnt = 0;
182                                                                 int t,r;
183                                                                 int flag = 1;                      //No.  status
184                                                                 if(status <= 5)                    //1    1
185                                                                 {                                  //2    12
186                                                                     for(t=1;t<=status+1;t++)       //3    123
187                                                                         cnt += abs(E[t]-SS[h[t]]); //4    1234
188                                                                     for(t;t<=6;t++)                //5    12345
189                                                                         if(E[t] != SS[h[t]])       //6    123456
190                                                                         {                          //7    16
191                                                                             flag = 0;              //8    126
192                                                                             break;                 //9    1236
193                                                                         }                          //10   12346
194                                                                     if(!flag)
195                                                                         continue;
196                                                                 }
197                                                                 else if(status >= 6 && status <= 9)
198                                                                 {
199                                                                     for(r=1;r<=status-5;r++)
200                                                                         cnt += abs(E[r]-SS[h[r]]);
201                                                                     for(r;r<6;r++)
202                                                                         if(E[r] != SS[h[r]])
203                                                                         {
204                                                                             flag = 0;
205                                                                             break;
206                                                                         }
207                                                                     if(!flag)
208                                                                         continue;
209                                                                     cnt += abs(E[6]-SS[h[6]]);
210                                                                 }
211                                                                 ans = min(ans,dis[h[1]][h[2]][h[3]][h[4]][h[5]][h[6]][pot][status]+cnt);
212                                                             }
213                                                         }
214                                                     }
215                                                 }
216                                             }
217                                         }
218                                     }
219                                 }
220                             }
221                         }
222                     }
223                 }
224             }
225         }
226         printf("%d
",ans);
227     }
228     return 0;
229 }
原文地址:https://www.cnblogs.com/usedrosee/p/4286286.html