zoukankan      html  css  js  c++  java
  • hdu 1175 连连看【bfs】

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1175

    【题意】输入一个地图(由数字组成),进行q次询问,俩位置的数字若相同就连起来,输出YES,前提是拐外次数少于等于两次,否则输出NO。

    【分析】典型的bfs,只是许久未练,有点生疏了。

    AC代码:

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<queue>
     4 #include<limits.h>
     5 using namespace std;
     6 int direc[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};//方向依次为右、左、下、上
     7 int map[1005][1005],vis[1005][1005],m,n;
     8 //a为输入的2维向量,vis记录该点是否被访问过了,同时记录有转折次数,如果
     9 //新的转折次数小于以前访问时的转折次数那么更新,否则就不更新。
    10 typedef struct
    11 {
    12     int x,y,dir,corner;//x,y,为行数列数,dir为方向,corner为转角次数。
    13 }node;
    14 node s,e;//记录开始和结束
    15 void bfs()//宽度搜索
    16 {
    17     queue<node> q;
    18     node cur,pre;   //用来记录当前的节点和前一个进行比较
    19     s.dir = -1;//开始时无方向
    20     s.corner = 0;//开始时转角次数为0
    21     q.push(s);
    22     while(!q.empty())
    23     {
    24         pre = q.front();
    25         q.pop();
    26         if(pre.x == e.x && pre.y == e.y)
    27         {cout<<"YES"<<endl;return;}
    28         for(int i = 0; i < 4; i++)//对节点的四个方向分别进行判断
    29         {
    30             cur.x = pre.x + direc[i][0];
    31             cur.y = pre.y + direc[i][1];
    32             cur.corner = pre.corner;      //令当前转角次数和前一个相同
    33             cur.dir = i;                  //当前方向
    34             //前一个不能使开始出,且当前方向和前一个方向不一致是转折次数自增1
    35             if(pre.dir != cur.dir && pre.dir != -1) cur.corner++;
    36             //判断是否出界,转角次数是否超过限制
    37             if(cur.x<1||cur.y<1||cur.x>n||cur.y>m||cur.corner>2) continue;
    38             //如果当前位置有数字存在,且当前位置不是终结位置,违反规则
    39             if(map[cur.x][cur.y]&&!(cur.x==e.x&&cur.y==e.y)) continue;
    40             if(cur.corner<vis[cur.x][cur.y])
    41             {
    42                 vis[cur.x][cur.y] = cur.corner;
    43                 q.push(cur);
    44             }
    45         }
    46     }
    47     cout<<"NO"<<endl;
    48 }
    49 int main()
    50 {
    51     int q;
    52     while(scanf("%d%d",&n,&m),n,m)
    53     {
    54         for(int i = 1; i <= n; i++)
    55         for(int j = 1; j <= m; j++)
    56         scanf("%d",&map[i][j]);
    57         scanf("%d",&q);
    58         while(q--)
    59         {
    60             scanf("%d%d%d%d",&s.x,&s.y,&e.x,&e.y);
    61             if(s.x==e.x&&s.y==e.y)//开始和结束在同一个位置
    62             {cout<<"NO"<<endl;continue;}
    63             //开始和结束位置没有数字或者开始和结束位置的数字不等。
    64             if(!map[s.x][s.y]||!map[e.x][e.y]||(map[s.x][s.y]!=map[e.x][e.y]))
    65             {cout<<"NO"<<endl;continue;}
    66 
    67             for(int i = 1; i <= n; i++)
    68                 for(int j = 1; j <= m; j++)
    69                     vis[i][j] = INT_MAX;  
    70             bfs();
    71         }
    72     }
    73     return 0;
    74 }
  • 相关阅读:
    编写OracleMembershipProvider,让SharePoint2007使用Oralce中的用户数据实现Form验证。 (第三天)
    学习《Building Applications with FME Objects》 之一 关于FME Objects
    我们在这里期待~~
    用python写fme数据转换脚本
    学习《Building Applications with FME Objects》 之七 坐标系统
    菜鸟笔记Linq初学 top(2)
    菜鸟笔记Linq初学 top(1)
    Sqlserver2008R2搭建本地服务器
    Python3之列表、元组和购物车程序练习
    Python3之字符串
  • 原文地址:https://www.cnblogs.com/123tang/p/6058199.html
Copyright © 2011-2022 走看看