• UVA10085隐式图搜索+八数码特殊节点记录优化


      1 /*八数码问题UVA10085:
      2 隐式图搜索:
      3 我觉得解决这类问题,有几点很重要:
      4 1、状态的表示(压缩状态表示可以减小空间复杂度)
      5 2、时间复杂度(状态数)的正确评估,你要保证暴力法是可以解决的。换句话说,状态很快会被填满
      6 3、编码的细心程度(废话,不过算法简单的话,对编码的要求自然就高了很多)
      7 
      8 显然,这道题的状态上限是9!=3*1e6,实际上是一道dfs求最大深度的题目
      9 */
     10 #include <stdio.h>
     11 #include <stdlib.h>
     12 #include <string.h>
     13 #include <math.h>
     14 #include <ctype.h>
     15 #include <string>
     16 #include <iostream>
     17 #include <sstream>
     18 #include <vector>
     19 #include <queue>
     20 #include <stack>
     21 #include <map>
     22 #include <list>
     23 #include <set>
     24 #include <algorithm>
     25 #define INF 1e10
     26 #define maxn 2000+10
     27 
     28 using namespace std;
     29 int vis[362880],fact[9];
     30 struct ret
     31 {
     32     int a[5][5];
     33 
     34 };
     35 struct Node{
     36     ret sta;
     37     int x,y;//记录当前空白格的位置,减少常数9的复杂度
     38     int deep;//bfs深度
     39     char step[maxn];
     40     void print()
     41     {
     42         for(int i=0;i<3;i++)
     43         {
     44             for(int j=0;j<3;j++)
     45             {
     46                 cout<<sta.a[i][j];
     47                 if (j<=1) cout<<" ";
     48             }
     49             cout<<endl;
     50         }
     51     }
     52 };
     53 void init_lookup_table()
     54 {
     55     memset(vis,0,sizeof(vis));
     56     fact[0]=1;
     57     for(int i=1;i<9;i++) fact[i]=fact[i-1]*i;
     58 }
     59 int try_to_insert(ret R)
     60 {
     61 
     62     int st[10];
     63     for(int i=0;i<3;i++)
     64     for(int j=0;j<3;j++)
     65        st[i*3+j]=R.a[i][j];
     66 //    for(int i=0;i<9;i++) cout<<st[i]<<" ";cout<<endl;
     67     int code=0;
     68     for(int i=0;i<9;i++)
     69     {
     70         int cnt=0;
     71         for(int j=i+1;j<9;j++) if (st[j]<st[i]) cnt++;
     72         code+=fact[8-i]*cnt;
     73 
     74     }
     75 //    cout<<code<<endl;
     76     if (vis[code]) return 0;
     77     return vis[code]=1;
     78 }
     79 
     80 int GetNum(ret x)//状态唯一确定数字
     81 {
     82     int ans=0;
     83     for(int i=0;i<3;i++)
     84     for(int j=0;j<3;j++)
     85     {
     86         ans+=x.a[i][j]*pow(10,(i*3+j));
     87     }
     88     return ans;
     89 }
     90 bool check(Node no,char c)
     91 {
     92     int x=no.x,y=no.y;
     93     if (c=='U') return (x-1)>=0;//一开始写成了>,OTL
     94     if (c=='D') return (x+1)<3;
     95     if (c=='L') return (y-1)>=0;
     96     if (c=='R') return (y+1)<3;
     97 
     98 }
     99 Node Move(Node no,char c)
    100 {
    101     int x=no.x,y=no.y;
    102     if (c=='U') {swap(no.sta.a[x][y],no.sta.a[x-1][y]);no.x--;no.step[no.deep++]='U';}
    103     if (c=='D') {swap(no.sta.a[x][y],no.sta.a[x+1][y]);no.x++;no.step[no.deep++]='D';}
    104     if (c=='L') {swap(no.sta.a[x][y],no.sta.a[x][y-1]);no.y--;no.step[no.deep++]='L';}
    105     if (c=='R') {swap(no.sta.a[x][y],no.sta.a[x][y+1]);no.y++;no.step[no.deep++]='R';}
    106     return no;
    107 }
    108 int nextint(){int x;scanf("%d",&x);return x;}
    109 void solve(int t)
    110 {
    111     int dpest=-1;Node ans;ret R;int sx,sy;
    112 
    113     init_lookup_table();
    114     queue<Node>Q;
    115 
    116     for(int i=0;i<3;i++)
    117     for(int j=0;j<3;j++){
    118         R.a[i][j]=nextint();
    119         if (R.a[i][j]==0) {sx=i;sy=j;}
    120     }
    121     Q.push((Node){R,sx,sy,0});
    122 
    123     while(!Q.empty())
    124     {
    125         Node no=Q.front();Q.pop();
    126 //        no.print();
    127         if (!try_to_insert(no.sta)) continue;
    128 //        cout<<"<<<"<<endl;
    129         if (no.deep>dpest) {dpest=no.deep;ans=no;}
    130 
    131         int x=no.x,y=no.y;
    132         //向上
    133         if (check(no,'U'))
    134             {Node newn=Move(no,'U');Q.push(newn);}
    135         if (check(no,'D'))
    136             {Node newn=Move(no,'D');Q.push(newn);}
    137         if (check(no,'L'))
    138             {Node newn=Move(no,'L');Q.push(newn);}
    139         if (check(no,'R'))
    140             {Node newn=Move(no,'R');Q.push(newn);}
    141     }
    142     printf("Puzzle #%d
    ",t);
    143     ans.print();
    144     ans.step[ans.deep]='';
    145     printf("%s
    ",ans.step);
    146     cout<<endl;
    147     return ;
    148 }
    149 int t;
    150 int main()
    151 {
    152     cin>>t;
    153     for(int i=1;i<=t;i++)
    154     solve(i);
    155 
    156     return 0;
    157 }
  • 相关阅读:
    2.17NOIP模拟赛(by hzwer) T2 小奇的序列
    2.17NOIP模拟赛(by hzwer) T1 小奇挖矿
    题解【洛谷P3662】[USACO17FEB]Why Did the Cow Cross the Road II S
    题解【CF886B】Vlad and Cafes
    题解【CJOJ1070/UVA】嵌套矩形
    题解 【CF381A】 Sereja and Dima
    何时使用UI层的智能表单技术
    开机加电到系统打开究竟发生了什么?(1)
    asp.net MVC 常见安全问题及解决方案
    HDU 4422 The Little Girl who Picks Mushrooms【水题】
  • 原文地址:https://www.cnblogs.com/little-w/p/3583580.html
Copyright © 2020-2023  润新知