zoukankan      html  css  js  c++  java
  • 15 Puzzle LightOJ

    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
    ",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
    ",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
    ",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
    ",maxd);
    130             if(fl)    break;
    131         }
    132         //printf("2t%d
    ",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

  • 相关阅读:
    leetcode 18 4Sum
    leetcode 71 Simplify Path
    leetcode 10 Regular Expression Matching
    leetcode 30 Substring with Concatenation of All Words
    leetcode 355 Design Twitte
    leetcode LRU Cache
    leetcode 3Sum
    leetcode Letter Combinations of a Phone Number
    leetcode Remove Nth Node From End of List
    leetcode Valid Parentheses
  • 原文地址:https://www.cnblogs.com/hehe54321/p/10420599.html
Copyright © 2011-2022 走看看