连连看 1175 HDU(广度搜索)

问题描述:http://acm.hdu.edu.cn/showproblem.php?pid=1175

思路很清晰,但是因为实现的方式和代码的问题,纠结了好久,最后请牛人(YWJ)帮忙,终于好了。

采用广度搜索,队列实现,先入先出,实现的时候,关键是对走过的路径的标识,防止陷入死循环。用数组has[][]标记一个点最小的拐角数。还有设立方向数组op[][],只要一个for就解决了四个方向,防止代码的重复。当然要注意判断下一步压入队列的和当前位置的关系,到底有没有拐角等。还有当拐角大于2时直接无视掉。

程序代码:

#include<iostream>
#include<queue>
using namespace std;
int res[1010][1010];//保存数组
int has[1010][1010];//标记到该节点最少的拐角(重点。。。)
int op[4][2]={-1,0,1,0,0,1,0,-1};
struct node
{
	int x;
	int y;
	int step;//标记拐角数
	int id;//标记方向,-1直走,0,1,2,3分别是向上,下,右,左
};
queue<node> myQue;
bool run(int x1,int y1,int x2,int y2,int n,int m)
{
	int i,j;
	int x,y;
	node temp,now;
	for(i=1;i<=n;i++)
		for(j=1;j<=m;j++)
			has[i][j]=5;
	while(!myQue.empty())
		myQue.pop();
	temp.x=x1;
	temp.y=y1;
	temp.step=-1;
	temp.id=-1;
	myQue.push(temp);
	has[x1][y1]=-1;
	while(!myQue.empty())
	{
		temp=myQue.front();
		myQue.pop();
		//如果前一步不是直走到,那么按其直走的方向走一步。因为额for循环中没有走。
		for(i=0;i<4;i++)
		{	
			//如果拐弯数大于等于二的时候不能拐弯
			if(temp.step>=2&&temp.id!=i) continue;
			x=temp.x+op[i][0];
			y=temp.y+op[i][1];
			if(x==x2&&y==y2) return true;
			if(x<1||x>n||y<1||y>m) continue;
			if(res[x][y]!=0) continue;
			now.x=x;
			now.y=y;
			if(i==temp.id)
			{
				now.step=temp.step;
				now.id=temp.id;
			}else{
				now.id=i;
				now.step=temp.step+1;
			}
			//若经过该点的拐角数比保存的要小,则入队列
			if(has[now.x][now.y]>=now.step)
			{
			
				has[now.x][now.y]=now.step;
				myQue.push(now);
			}
		}	
	}
	return false;
}
int main(int argc, char* argv[])
{
	int n,m;
	int i,j;
	int t,a,b,c,d;
	while(cin>>n>>m)
	{
		if(n==0&&m==0)
			break;
		for(i=1;i<=n;i++)
			for(j=1;j<=m;j++)
				cin>>res[i][j];
		cin>>t;
		while(t--)
		{
			cin>>a>>b>>c>>d;
			if(res[a][b]==0||res[c][d]==0||(a==c&&b==d))
			{
				cout<<"NO"<<endl;
				continue;
			}
			if(res[a][b]!=res[c][d])
				cout<<"NO"<<endl;
			else if(run(a,b,c,d,n,m))
					cout<<"YES"<<endl;
			else cout<<"NO"<<endl;
		}
	}
	return 0;
}


你可能感兴趣的:(c,struct)