当前位置: 代码迷 >> 综合 >> HOJ 1175 连连看(bfs)
  详细解决方案

HOJ 1175 连连看(bfs)

热度:93   发布时间:2023-12-13 19:07:02.0

bfs
本题要点:
1、连连看,先保证起点和终点,都不是0,且相等。
2、然后从起点 s 开始bfs, 用 step 记录拐弯次数。拐弯不超过两次。
3、direction 表示,进入点 (x, y) ,是从哪个方向进来的。
比如某一点 (x, y), 它的 direction == 0, 表示 (x, y)的上一点 是 从 左右方向进入 (x, y)。
此时,点(x, y) 的下一点,只需要从上下方向寻找。
4、点(x, y) 沿着上方向,一直走,直到不能走为止。所谓不能走,就是说,遇到非空白的地方。
当遇到 终点 t,表示可以找到一条路径(拐弯次数不超过2次), 从s到t。
代码较长,其中四个方向都是类似的代码。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
const int MaxN = 1010;
int n, m, query;
int mp[MaxN][MaxN];
bool vis[MaxN][MaxN];struct node
{
    int x, y, step;int direction;	//direction 表示,进入点 (x, y) ,是从哪个方向进来的
};					// direction == 0, 表示从 左右方向; direction == 0 表示从上下方向。 direction == -1, 表示点(x, y) 是起点
node s, t;bool judge(int x, int y)
{
    return x >= 1 && x <= n && y >= 1 && y <= m;
}void bfs()
{
    for(int i = 0; i <= n; ++i)for(int j = 0; j <= m; ++j)vis[i][j] = false;int ax, ay;node tmp;s.step = -1, s.direction = -1;queue<node> q;q.push(s);vis[s.x][s.y] = true;while(q.size()){
    node now = q.front();q.pop();ax = now.x, ay = now.y;	if(now.step >= 2)	continue;if(now.direction == -1 || now.direction == 1)// 往左,右{
    ax = now.x, ay = now.y;	while(true) // 往左{
    if(judge(ax, ay - 1) == false)	break;if(!(ax == t.x && ay - 1 == t.y) && mp[ax][ay - 1] == 0){
    if(vis[ax][ay - 1] == false)	{
    vis[ax][ay - 1] = true;tmp.x = ax, tmp.y = ay - 1, tmp.direction = 0, tmp.step = now.step + 1;q.push(tmp);}}else{
    if(ax == t.x && ay - 1 == t.y){
    printf("YES\n");return;}break;}--ay;}ax = now.x, ay = now.y;	while(true){
    if(judge(ax, ay + 1) == false)	break;if(!(ax == t.x && ay + 1 == t.y) && mp[ax][ay + 1] == 0){
    if(vis[ax][ay + 1] == false)	{
    vis[ax][ay + 1] = true;tmp.x = ax, tmp.y = ay + 1, tmp.direction = 0, tmp.step = now.step + 1;q.push(tmp);}}else{
    if(ax == t.x && ay + 1 == t.y){
    printf("YES\n");return;}break;}++ay;}}//往上,下if(now.direction == -1 || now.direction == 0){
    ax = now.x, ay = now.y;	while(true)	// 上{
    if(judge(ax - 1, ay) == false)  break;if(!(ax - 1 == t.x && ay == t.y) && mp[ax - 1][ay] == 0){
    if(vis[ax - 1][ay] == false){
    vis[ax - 1][ay] = true;tmp.x = ax - 1, tmp.y = ay, tmp.direction = 1, tmp.step = now.step + 1;q.push(tmp);}}else{
    if(ax - 1 == t.x && ay == t.y){
    printf("YES\n");return;}break;}--ax;}ax = now.x, ay = now.y;	while(true)	// 下{
    if(judge(ax + 1, ay) == false)  break;if(!(ax + 1 == t.x && ay == t.y) && mp[ax + 1][ay] == 0){
    if(vis[ax + 1][ay] == false){
    vis[ax + 1][ay] = true;tmp.x = ax + 1, tmp.y = ay, tmp.direction = 1, tmp.step = now.step + 1;q.push(tmp);}}else{
    if(ax + 1 == t.x && ay == t.y){
    printf("YES\n");return;}break;}++ax;}}}printf("NO\n");
}int main()
{
    while(scanf("%d%d", &n, &m) != EOF){
    if(0 == n && 0 == m)	break;for(int i = 1; i <= n; ++i){
    for(int j = 1; j <= m; ++j){
    scanf("%d", &mp[i][j]);}}scanf("%d", &query);for(int i = 0; i < query; ++i){
    scanf("%d%d%d%d", &s.x, &s.y, &t.x, &t.y);if(mp[s.x][s.y] == 0 || mp[t.x][t.y] == 0 || (mp[s.x][s.y] != mp[t.x][t.y])){
    printf("NO\n");}elsebfs();}}return 0;
}/* 3 4 1 2 3 4 0 0 0 0 4 3 2 1 4 1 1 3 4 1 1 2 4 1 1 3 3 2 1 2 4 3 4 0 1 4 3 0 2 4 1 0 0 0 0 2 1 1 2 4 1 3 2 3 0 0 *//* YES NO NO NO NO YES */