15 Puzzle LightOJ - 1121

https://cn.vjudge.net/problem/LightOJ-1121

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<vector>
  5 using namespace std;
  6 #define fi first
  7 #define se second
  8 #define mp make_pair
  9 #define pb push_back
 10 typedef long long ll;
 11 typedef unsigned long long ull;
 12 char /*ans[1011],*/now[40];int len;
 13 int x,y,a[4][4];//xx1[4][4]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0};
 14 int xx2[16][2]={{3,3},{0,0},{0,1},{0,2},{0,3},{1,0},{1,1},{1,2},{1,3},
 15     {2,0},{2,1},{2,2},{2,3},{3,0},{3,1},{3,2}};
 16 bool fl;
 17 int T,n,maxd;
 18 inline int abs1(int x){return x>0?x:-x;}
 19 //估价函数:除0以外,所有数当前位置与目标位置的曼哈顿距离之和
 20 int hh()
 21 {
 22     int i,j,cnt=0;
 23     for(i=0;i<4;++i)
 24         for(j=0;j<4;++j)
 25             if(a[i][j])
 26                 cnt+=abs1(i-xx2[a[i][j]][0])+abs1(j-xx2[a[i][j]][1]);
 27     return cnt;
 28 }
 29 inline void swap1(int &a,int &b)
 30 {
 31     int t=a;a=b;b=t;
 32 }
 33 //#define swap(a,b) {t=a;a=b;b=t;}
 34 #define swap swap1
 35 void dfs(int d,char pre)
 36 {
 37     //printf("1t%d\n",d);
 38     int h=hh();
 39     if(!h)    {fl=1;/*memcpy(ans,now,sizeof(char)*(len+1));*/return;}
 40     if(d+h>maxd)    return;
 41     if(x!=3 && pre!='U')
 42     {
 43         //now[++len]='D';
 44         swap(a[x][y],a[x+1][y]);++x;
 45         dfs(d+1,'D');
 46         if(fl)    {now[++len]='D';return;}
 47         //--len;
 48         --x;swap(a[x][y],a[x+1][y]);
 49     }
 50     if(y!=0 && pre!='R')
 51     {
 52         //now[++len]='L';
 53         swap(a[x][y-1],a[x][y]);--y;
 54         dfs(d+1,'L');
 55         if(fl)    {now[++len]='L';return;}
 56         //--len;
 57         ++y;swap(a[x][y-1],a[x][y]);
 58     }
 59     if(y!=3 && pre!='L')
 60     {
 61         //now[++len]='R';
 62         swap(a[x][y+1],a[x][y]);++y;
 63         dfs(d+1,'R');
 64         if(fl)    {now[++len]='R';return;}
 65         //--len;
 66         --y;swap(a[x][y+1],a[x][y]);
 67     }
 68     if(x!=0 && pre!='D')//不要让操作刚好抵消上一次操作,实测很有效
 69     {
 70         //now[++len]='U';
 71         swap(a[x][y],a[x-1][y]);--x;
 72         dfs(d+1,'U');
 73         if(fl)    {now[++len]='U';return;}
 74         //--len;
 75         ++x;swap(a[x][y],a[x-1][y]);
 76     }
 77 }
 78 /*
 79     判无解,
 80     https://blog.csdn.net/obsorb_knowledge/article/details/79915484
 81     A=将16个数排成一行,((0,0),(0,1),(0,2),(0,3),(1,0),(1,1),..的顺序)
 82     删去0,当前状态这么做之后的逆序对数与目标状态奇偶性是否相同
 83     (相同为1,不同为0)
 84     B=当前状态0的行号与目标状态的奇偶性是否相同
 85     有解要求满足:A==B
 86 */
 87 bool judge()
 88 {
 89     int tmp[16],x0,i,j;
 90     tmp[0]=0;
 91     for(i=0;i<4;++i)
 92         for(j=0;j<4;++j)
 93             if(a[i][j])
 94                 tmp[++tmp[0]]=a[i][j];
 95             else
 96                 x0=i;
 97     //for(i=1;i<=15;++i)
 98     //    printf("1t%d\n",tmp[i]);
 99     int a1=0;
100     for(i=1;i<=15;++i)
101         for(j=1;j<i;++j)
102             if(tmp[j]>tmp[i])
103                 ++a1;
104     //printf("2t%d %d\n",a1&1,3-x0);
105     return (a1&1)==((3-x0)&1);
106 }
107 int main()
108 {
109     int i,j;
110     scanf("%d",&T);
111     for(int TT=1;TT<=T;++TT)
112     {
113         fl=0;len=0;
114         for(i=0;i<4;++i)
115             for(j=0;j<4;++j)
116             {
117                 scanf("%d",&a[i][j]);
118                 if(a[i][j]==0)    x=i,y=j;
119             }
120         printf("Case %d: ",TT);
121         if(!judge())
122         {
123             puts("This puzzle is not solvable.");
124             continue;
125         }
126         for(maxd=0;maxd<=35;++maxd)
127         {
128             dfs(0,0);
129             //printf("1t%d\n",maxd);
130             if(fl)    break;
131         }
132         //printf("2t%d\n",maxd);
133         if(fl)
134         {
135             for(i=len;i>=1;--i)
136                 printf("%c",now[i]);
137             puts("");
138         }
139         else
140             puts("This puzzle is not solvable.");
141     }
142     return 0;
143 }
View Code

另有

https://cn.vjudge.net/problem/SCU-1110

https://cn.vjudge.net/problem/UVA-10181

 

posted @ 2019-02-22 20:44  hehe_54321  阅读(322)  评论(0编辑  收藏  举报
AmazingCounters.com