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 977 有序数组的平方
    LeetCode 24 两两交换链表中的节点
    LeetCode 416 分割等和子集
    LeetCode 142 环形链表II
    LeetCode 106 从中序与后序遍历序列构造二叉树
    LeetCode 637 二叉树的层平均值
    LeetCode 117 填充每个节点的下一个右侧节点
    LeetCode 75 颜色分类
    redhat 7.4 挂载ntfs格式的u盘并且使用
    redhat 查看CPU frequency scaling(CPU频率缩放)
  • 原文地址:https://www.cnblogs.com/hehe54321/p/10420599.html
Copyright © 2011-2022 走看看