zoukankan      html  css  js  c++  java
  • 算法 hdoj 连连看 BFS 木

    hdoj 1175 http://acm.hdu.edu.cn/showproblem.php?pid=1175

    这题是简单的搜索,给图图中的两个位置,问这两个位置是否可以消去。

    有以下情况不能消去:

    1,起点和终点有任意一个是非法点,即不是图中的点;

    2,起点和终点有任意一个是数值为0的点,即该点事空的。

    3,起点和终点的数值不相同。

    4,起点和终点的最短距离大于2,这个最短距离是指转弯的次数。

    前3点都是直接可以处理的,对于第四点我是采用bfs搜的。记录当前节点的方向和转弯次数即可。

    在hdoj c++ 提交 跑了109ms, 弱啊 ! 

    View Code
     1 // 用node记录上一次的方向,但是结束条件不是找到终点就返回结果,这样会出错// 
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <queue>
     5 #include <cstring>
     6 #include <algorithm>
     7 using namespace std;
     8 
     9 #define maxn 1088
    10 int n, m;
    11 int g[maxn][maxn];
    12 int step[4][2]={{0,-1}, {0,1},{1,0},{-1,0} };
    13 
    14 void init(){
    15      for ( int i=1; i<=n; ++i )
    16        for ( int j=1; j<=m; ++j )
    17         scanf ("%d", &g[i][j]);
    18 }
    19 
    20 struct Node{
    21     int  x, y;
    22     Node(){}
    23     Node(int X, int Y):x(X), y(Y){}
    24     void scan(){
    25         scanf("%d%d", &x, &y);
    26     }
    27 }s, e;
    28 
    29 int dist[maxn][maxn];
    30 
    31 // 判断两个节点是否相等
    32 bool is(Node a, Node b){
    33    return ( a.x==b.x && a.y==b.y);
    34 }
    35 // 判断点是否合法
    36 bool ok(int x, int y){
    37   if(x<1 || y<1 || x>n || y>m) return 0;
    38   return 1;
    39 }
    40 
    41 bool bfs(Node a, Node b) {
    42     if(!ok(a.x, a.y) || !ok(b.x, b.y)) return 0;
    43     if(g[a.x][a.y] != g[b.x][b.y]) return 0;
    44     if(!g[a.x][a.y] || !g[b.x][b.y]) return 0;
    45     if(is(a, b) ) return 0;
    46     
    47     for ( int i=1; i<=n; ++i )
    48       for ( int j=1; j<=m; ++j )
    49       dist[i][j] = 30000;
    50 
    51     queue<Node > Q;
    52     while(!Q.empty() ) Q.pop();
    53     Q.push( a );  dist[s.x ][s.y]=0;
    54     Q.push( Node(0,0) );
    55 
    56     while(!Q.empty() ) {
    57          Node current = Q.front(); Q.pop();
    58          Node last_direct = Q.front(); Q.pop();
    59 
    60          for ( int i=0; i<4; ++i ){
    61              int xx = current.x+ step[i][0];
    62              int yy = current.y+ step[i][1];
    63              if(!ok(xx, yy) ) continue;
    64              //cout <<xx << " " << yy << endl;
    65              int d = dist[current.x][current.y];
    66              if(!is(last_direct, Node(step[i][0], step[i][1])) ) ++d;
    67 
    68              if(is(Node(xx, yy), e )  ) { // 节点是终点
    69                  dist[xx][yy] = min(dist[xx][yy], d);
    70                  if(dist[xx][yy] < 4) return 1;
    71              }
    72 
    73              if(!g[xx][yy] && dist[xx][yy] > d){ 
    74               // 入队列的只能是空点,而且是距离更新过的
    75                 dist[xx][yy] = d;
    76                 if(d > 3) continue;
    77                 Q.push(Node(xx, yy) );
    78                 Q.push(Node(step[i][0], step[i][1]) );
    79              }
    80          }
    81     }
    82     return 0;
    83 };
    84 
    85 void solve(){
    86     int q;  scanf("%d", &q);
    87     while( q-- ) {
    88         s.scan(); e.scan();
    89         if( bfs(s, e) ) puts("YES");
    90         else puts("NO");
    91     }
    92 }
    93 int main(){
    94     while( scanf("%d%d", &n, &m), n||m ){
    95         init();
    96         solve();
    97     }
    98 };

     突然想起记录方向时直接用一个数值表示就号可以了,我代码中的记录方法麻烦。。

  • 相关阅读:
    AdminLTE组件之表格DataTable
    爬虫:通过滑动或者点触验证码的方法及实现(点触+滑动)
    爬虫:滑动验证解决方法及python实现
    django文件上传地址以及media的设置
    基于cropper和sweetalert的简单图片/头像裁剪上传
    学写网站(二)前端配置之glup
    轩辕剑陆和外传平台版设置功能
    植物大战僵尸
    仙剑类更新
    VSCode注册关联自定义类型文件
  • 原文地址:https://www.cnblogs.com/TengXunGuanFangBlog/p/BFS.html
Copyright © 2011-2022 走看看