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

  • 相关阅读:
    委托和异步方法
    线程池_ThreadPool
    委托_deleget
    一步一步实现视频播放器client(二)
    mysql忘记password
    POJ 2456 Aggressive cows (二分 基础)
    Fragment小结
    Cocos2d-x粒子系统
    淘宝数据库OceanBase SQL编译器部分 源代码阅读--解析SQL语法树
    C与C++在形參的一点小差别
  • 原文地址:https://www.cnblogs.com/hehe54321/p/10420599.html
Copyright © 2011-2022 走看看