#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
/*
本题所得; 深搜的难点是剪枝, 对于搜索,我们一定要尽量控制进入递归搜索的次数, 对于题目给出的数据
尽量找到不合题意的情况, 将其剪去; 在递归中也是一样,想尽一切办法剪枝,
*/
int mmap[1005][1005];
int vist[1005][1005];
int n, m;
int T;
int flag, t, pos;
int dir[][2] = {{1, 0}, {-1, 0}, {0, -1}, {0, 1} };
int judge(int x, int y) {
if(x >= 1 && x <= n && y >= 1 && y <= m && vist[x][y] == 0)
return 1;
return 0;
}
/* 本代码 转弯从1 开始, 顾可以转三次;
void dfs(int x, int y, int a, int b) {
if(t)
return;
if(x == a && y == b) { //找到目标,且步数少于3;
if(pos <= 3)
t = 1;
return ;
}
if(pos > 3) //步数大于3 , 剪枝;
return ;
if(mmap[x][y] != 0 && flag != 0) {//当前格不是通路, 但要除去开始搜索处,flag = 0 的情况;
return;
}
if(pos == 3 && x - a != 0 && y - b != 0) // 当前转弯次数为3, x - a != 0 && y - b != 0 则要到达目标一定还要转弯;
return; //顾剪枝;
vist[x][y] = 1; //当前不标记为 走过;
for(int i = 0; i < 4; i++) { //用i 从1 到4 表示四个方向;
int nextx = x + dir[i][0];
int nexty = y + dir[i][1];
int temp = flag; //保留当前,方向;
if(!vist[nextx][nexty] && nextx >= 1 && nexty >= 1 && nextx <= n && nexty <= m)
{
if(flag != i + 1) //判断是否与当前方向相同;
{
pos++; //表示改变方向数加一;
flag = i + 1; //更新当前方向;
dfs(nextx, nexty, a, b);
pos--; //还原当前方向改变数;
}
else
{
flag = i + 1;
dfs(nextx, nexty, a, b);
}
flag = temp; //还原当前方向;
}
}
vist[x][y] = 0;//当前点还原为未走过;
}
int main()
{
int sx, sy, ex, ey;
while(scanf("%d%d", &n, &m) != EOF)
{
if(m == 0 && m == 0)
break;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
scanf("%d", &mmap[i][j]);
vist[i][j] =0;
}
}
scanf("%d", &T);
while(T--)
{
flag = 0;
t = 0;
pos = 0;
scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
if(mmap[sx][sy] == mmap[ex][ey] && mmap[sx][sy] != 0)
{
dfs(sx, sy, ex, ey);
if(t)
printf("YES\n");
else
printf("NO\n");
}
else
printf("NO\n");
}
}
return 0;
}
hud 1175 连连看
最新推荐文章于 2017-02-18 16:38:25 发布