您的位置:首页 > 其它

1009

2016-04-23 23:33 190 查看
题目标号:1009

题目大意:连连看。给你一个数组表示地图,0表示空,给N组2对坐标,判断是否可以消去,只能从中间空的过,不能从外面走。

解题思路:这题是个复杂的深搜,主要难度在于如何剪枝判断。我们先这样想,一个人走路,在空地上走,他可以往前后左右四个方位,他需要到达离他有段距离的某地。他应该                        先判断那点在他的什么方向上,然后有2种方法:先走再拐弯或者先拐弯再走。标记一下他拐弯的次数,可以发现,他拐第3次就相当于往回走了,那就更不要考虑更多                      的次数了。如果理解这种情况,那可以考虑这题了。首先,数组存地图,然后给2对坐标,先判断是不是2个不同的坐标和地图上两个点数值是不是相同,可以提前结
                         束。创建个标记的数组,进行储存是否走过的路。开始深搜。深搜的4个参数分别是,X1的横坐标,X1的纵坐标,a是指拐弯次数,b是标记上次的方向看是否与下次相                            同,相同就不用在拐弯次数加1,不同的话就加1次。在函数里,有许多剪枝:拐弯大于等于3,越界,正好到目标点等。最后如果还没有找到就标记回来,也就是退回                       来选另一个路。退出函数再进行外循环。

做题感想:第一次遇到这种剪枝,很不容易想,最主要的还是因为自己做题少了,见识少了。做题也是拓展眼界的重要方法。#include<iostream>
#include<cstring>
using namespace std;
int map[1001][1001],N,M,x1,x2,y1,y2;
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
int arr[1001][1001],i,j;
bool f;
void dfs(int x,int y,int a,int b)
{
if(f)
return;
if(a>=3)
return;
if(x==x2&&y==y2)
{
f=true;
return;
}
if(x<0||y<0||x>=N||y>=M||map[x][y]!=0||arr[x][y])
return;
if(a==2)
{
if(!(b==0&&y2==y&&x2<x||b==1&&y2==y&&x2>x||b==2&&y2<y&&x2==x||b==3&&y2>y&&x2==x))
return;
}
arr[x][y]=1;
for(i=0;i<4;i++)
{
if(i==b)
dfs(x+dx[i],y+dy[i],a,b);
else
dfs(x+dx[i],y+dy[i],a+1,i);
}
arr[x][y]=0;
}
int main()
{
int n;
while(cin>>N>>M&&(N||M))
{
for(i=0;i<N;i++)
for(j=0;j<M;j++)
cin>>map[i][j];
cin>>n;
while(n--)
{
cin>>x1>>y1>>x2>>y2;
x1--;
x2--;
y1--;
y2--;
f=false;
if((x1!=x2||y1!=y2)&&(map[x1][y1]==map[x2][y2])&&map[x1][y1]!=0)
{
memset(arr,0,sizeof(arr));
arr[x1][y1]=1;
for(i=0;i<4;i++)
dfs(x1+dx[i],y1+dy[i],0,i);
}
if(f)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: