我现在做的是第二专题编号为1009的试题,具体内容如下所示:
连连看
Time Limit : 20000/10000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 67 Accepted Submission(s) : 21
Problem Description
“连连看”相信很多人都玩过。没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子。如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子),而且线的转折次数不超过两次,那么这两个棋子就可以在棋盘上消去。不好意思,由于我以前没有玩过连连看,咨询了同学的意见,连线不能从外面绕过去的,但事实上这是错的。现在已经酿成大祸,就只能将错就错了,连线不能从外围绕过。<br>玩家鼠标先后点击两块棋子,试图将他们消去,然后游戏的后台判断这两个方格能不能消去。现在你的任务就是写这个后台程序。<br>
Input
输入数据有多组。每组数据的第一行有两个正整数n,m(0<n<=1000,0<m<1000),分别表示棋盘的行数与列数。在接下来的n行中,每行有m个非负整数描述棋盘的方格分布。0表示这个位置没有棋子,正整数表示棋子的类型。接下来的一行是一个正整数q(0<q<50),表示下面有q次询问。在接下来的q行里,每行有四个正整数x1,y1,x2,y2,表示询问第x1行y1列的棋子与第x2行y2列的棋子能不能消去。n=0,m=0时,输入结束。<br>注意:询问之间无先后关系,都是针对当前状态的!<br>
Output
每一组输入数据对应一行输出。如果能消去则输出"YES",不能则输出"NO"。<br>
Sample Input
3 4<br>1 2 3 4<br>0 0 0 0<br>4 3 2 1<br>4<br>1 1 3 4<br>1 1 2 4<br>1 1 3 3<br>2 1 2 4<br>3 4<br>0 1 4 3<br>0 2 4 1<br>0 0 0 0<br>2<br>1 1 2 4<br>1 3 2 3<br>0 0<br>
Sample Output
YES<br>NO<br>NO<br>NO<br>NO<br>YES<br>
简单题意:
判断是否能完成连连看,规则与我们玩的规则差不多,但不能从外围连线,这与传统的玩法有区别
解题思路:
这道题将BFS做一点小小的变形,即每次让一个方向的可能点全部入对列,这样能够使得拐弯次数限制到最小,标记的变量要设四个方向,每次走过的点要标记两个方向,向前和向后,显然不可能再次走到这一点以相同的方向或者反过来。其他就和一般的BFS差不多了
编写代码:
#include <cstring>
#include <queue>
#include <cstdlib>
#define INF 0x7f7f7f7f
using namespace std;
int map[1005][1005], hash[4][1005][1005], dir[4][2]= { 1, 0, -1, 0, 0, 1, 0, -1 };
struct Node
{
int x, y, type, ti, dir;
}info;
void gint( int &t )
{
char c;
while( c= getchar(), c< '0'|| c> '9' ) ;
t= c- '0';
while( c= getchar(), c>= '0'&& c<= '9' )
{
t= t* 10+ c- '0';
}
}
bool BFS( int sx, int sy, int ex, int ey )
{
queue< Node >q;
memset( hash, 0, sizeof( hash ) );
info.x= sx, info.y= sy, info.type= map[sx][sy], info.ti= 0, info.dir= -1;
hash[0][sx][sy]= hash[1][sx][sy]= hash[2][sx][sy]= hash[3][sx][sy]= 1;
q.push( info );
while( !q.empty() )
{
Node pos= q.front();
q.pop();
if( pos.x== ex&& pos.y== ey )
{
return true;
}
for( int i= 0; i< 4; ++i )
{
int x= pos.x+ dir[i][0], y=pos.y+ dir[i][1], ti= pos.ti, d= pos.dir;
while( ( map[x][y]== 0|| ( x== ex&& y== ey ) )&& !hash[i][x][y] )
{
int k= ( i== d|| d== -1 )? 0: 1;
info.x= x, info.y= y, info.ti= ti+ k, info.dir= i;
if( info.ti<= 2 )
{
if( info.ti< 2|| ( info.ti== 2 && ( x== ex|| y== ey ) ) )
{
q.push( info );
}
hash[i][x][y]= 1;
if( i== 0|| i== 1 )
{
hash[!i][x][y]= 1;
}
else if( i== 2 )
{
hash[3][x][y]= 1;
}
else
{
hash[2][x][y]= 1;
}
}
x+= dir[i][0], y+= dir[i][1];
}
}
}
return false;
}
int main()
{
int N, M;
while( scanf( "%d %d", &N, &M ), N| M )
{
memset( map, 0x7f, sizeof( map ) );
for( int i= 1; i<= N; ++i )
{
for( int j= 1; j<= M; ++j )
{
gint( map[i][j] );
}
}
int q;
scanf( "%d", &q );
while( q-- )
{
int sx, sy, ex, ey;
scanf( "%d %d %d %d", &sx, &sy, &ex, &ey );
if( ( map[sx][sy]!= map[ex][ey] )|| map[sx][sy]== 0|| map[ex][ey]== 0|| ( sx== ex&& sy== ey ) )
{
puts( "NO" );
continue;
}
printf( BFS( sx, sy, ex, ey )? "YES\n": "NO\n" );
}
}
return 0;
}