带拐点搜索,用广搜内存超出后用深搜,无限超时,还没有考虑到所有可能出现的情况,最后终于用最水最水的方法水过。。。
一个人努力真是辛苦啊http://acm.hdu.edu.cn/showproblem.php?pid=1175
#include <stdio.h>
#include "memory.h"
int map[1001][1001];
int vit[1001][1001];
int fangxiang[4][2]={1,0,-1,0,0,1,0,-1}; //四个方向深搜
int flag; //判断是否能找到
int n,m; //图的长宽
int bgx,bgy,endx,endy; //开始结束点
int cango(int x,int y) //判断是否是合理点
{
if(x>=1&&x<=n&&y>=1&&y<=m&&!vit[x][y]&&(map[x][y]==0||map[x][y]==map[endx][endy]&&x==endx&&y==endy))
{
return 1;
}
return 0;
}
void dfs(int tempx,int tempy,int turns,int toward) //起点,拐弯次数和朝向
{
if(map[tempx][tempy]==map[endx][endy]&&turns<=2&&toward!=-1) //找到终点
{
flag=1;
//printf("turns=%d \n",turns);
return ;
}
if(flag==1) //已经找到答案
{
return ;
}
if(turns>3) //拐弯超过三次了
{
return ;
}
//一会儿试试把这个去掉时间会加多少。 An:不去62MS,去了,7765MS。。。
if(turns==2&&tempx-endx!=0&&tempy-endy!=0)//拐了两次后一定在终点这一行或这一列
{
return ;
}
int i;
int nowtoward=toward; //记录现在的朝向
for(i=0;i<4;i++)
{
if(flag==1) //已经找到答案
{
return ;
}
int newx,newy;
newx=tempx+fangxiang[i][0];
newy=tempy+fangxiang[i][1];
if(cango(newx,newy)) //是合理结点
{
vit[newx][newy]=1; //当前结点已经访问
if(toward==-1) //还未确实方向的开始结点
{
dfs(newx,newy,turns,i);
}else if(toward!=i) //需要转向
{
dfs(newx,newy,turns+1,i);
}else if(toward==i) //不需要转向
{
dfs(newx,newy,turns,i);
}
vit[newx][newy]=0; // 回溯
// toward=nowtoward;
}
}
}
int main(int argc, char *argv[])
{
while(scanf("%d%d",&n,&m)) //图的长和宽
{
if(n==0&&m==0)
{
break;
}
int i,j;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
scanf("%d",&map[i][j]); //输入图的信息
}
}
//----------------询问----------------------
int query;
scanf("%d",&query);
int i2;
for(i2=0;i2<query;i2++)
{
memset(vit,0,sizeof(vit)); //开始时访问清零
scanf("%d%d%d%d",&bgx,&bgy,&endx,&endy);
flag=0; //初始化标记未找到
vit[bgx][bgy]=1;
dfs(bgx,bgy,0,-1); //以开始,次数和方向为参数开始深搜
if(map[bgx][bgy]!=map[endx][endy])
{
printf("NO\n");
}
else if(map[bgx][bgy]==0||map[endx][endy]==0)
{
printf("NO\n");
}
else{
if(flag==1)
{
printf("YES\n");
}else
{
printf("NO\n");
}
}
}
}
return 0;
}