zoukankan      html  css  js  c++  java
  • 【HAOI2008】移动玩具

    这是一道搜索题,我采用双向广搜+状压解决,对每一个状态枚举可以移动的位置,将状态扩展,然后通过对数组状压的方法进行记录结果。

    另外,注意对答案为0的特判,因为起始状态与目标状态相同时无法搜出结果。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <queue>
     5 #include <algorithm>
     6 using namespace std;
     7 struct node {
     8     int a[5][5];
     9 };
    10 queue<node> q1;
    11 queue<node> q2;
    12 int vis[1<<17];
    13 int dis[1<<17];
    14 const int fx[5]={0,0,0,1,-1};
    15 const int fy[5]={0,1,-1,0,0};
    16 inline int get(node k) {
    17     int num=0,ret=0;
    18     for(int i=1;i<=4;i++) {
    19         for(int j=1;j<=4;j++) {
    20             ret+=k.a[i][j]<<num++;
    21         }
    22     }
    23     return ret;
    24 }
    25 int bfs() {
    26     while(!q1.empty()&&!q2.empty()) {
    27         if(q1.size()<=q2.size()) {
    28             node now=q1.front();
    29             q1.pop();
    30             for(int i=1;i<=4;i++)
    31                 for(int j=1;j<=4;j++)
    32                     if(now.a[i][j]) {
    33                         for(int k=1;k<=4;k++) {
    34                             int xx=i+fx[k];
    35                             int yy=j+fy[k];
    36                             if(xx<1||xx>4||yy<1||yy>4) continue ;
    37                             if(!now.a[xx][yy]) {
    38                                 swap(now.a[i][j],now.a[xx][yy]);
    39                                 node neww;
    40                                 memcpy(neww.a,now.a,sizeof(now.a));
    41                                 swap(now.a[i][j],now.a[xx][yy]);
    42                                 int sum=get(neww);
    43                                 if(vis[get(now)]+vis[sum]==3) return dis[get(now)]+dis[sum];
    44                                 if(vis[sum]==1) continue ;
    45                                 q1.push(neww);
    46                                 vis[sum]=1;
    47                                 dis[sum]=dis[get(now)]+1;
    48                             }
    49                         }
    50                     }
    51         }
    52         else {
    53             node now=q2.front();
    54             q2.pop();
    55             for(int i=1;i<=4;i++)
    56                 for(int j=1;j<=4;j++)
    57                     if(now.a[i][j]) {
    58                         for(int k=1;k<=4;k++) {
    59                             int xx=i+fx[k];
    60                             int yy=j+fy[k];
    61                             if(xx<1||xx>4||yy<1||yy>4) continue ;
    62                             if(!now.a[xx][yy]) {
    63                                 swap(now.a[i][j],now.a[xx][yy]);
    64                                 node neww;
    65                                 memcpy(neww.a,now.a,sizeof(now.a));
    66                                 swap(now.a[i][j],now.a[xx][yy]);
    67                                 int sum=get(neww);
    68                                 if(vis[get(now)]+vis[sum]==3) return dis[get(now)]+dis[sum];
    69                                 if(vis[sum]==2) continue ;
    70                                 q2.push(neww);
    71                                 vis[sum]=2;
    72                                 dis[sum]=dis[get(now)]+1;
    73                             }
    74                         }
    75                     }
    76         }
    77     }
    78     return -999999;
    79 }
    80 int main() {
    81     node s,e;
    82     for(int i=1;i<=4;i++) {
    83         for(int j=1;j<=4;j++)
    84             scanf("%1d",&s.a[i][j]);
    85     }
    86     for(int i=1;i<=4;i++) {
    87         for(int j=1;j<=4;j++)
    88             scanf("%1d",&e.a[i][j]);
    89     }
    90     q1.push(s);
    91     q2.push(e);
    92     vis[get(s)]=1;
    93     vis[get(e)]=2;
    94     dis[get(s)]=0;
    95     dis[get(e)]=0;
    96     if(get(s)==get(e)) puts("0");
    97     else printf("%d
    ",bfs()+1);
    98     return 0;
    99 }
    AC Code
  • 相关阅读:
    微软校园招聘  研发工程师A
    版本号排序
    腾讯2018校园招聘  研发工程师笔试题(三)
    好词好句
    HikariCP 连接最快的连接池
    Ubuntu 18.04.1 安装java8
    Ubuntu 18.04.1 安装mysql 5.7.27
    markdown 插入链接
    面试题 int(3) int(10) 区别
    采购单(京东2017秋招真题)
  • 原文地址:https://www.cnblogs.com/shl-blog/p/10627482.html
Copyright © 2011-2022 走看看