連連看
題目描述:
“連連看”相信很多人都玩過。沒玩過也沒關係,下面我給大家介紹一下游戲規則:在一個棋盤中,放了很多的棋子。如果某兩個相同的棋子,可以通過一條線連起來(這條線不能經過其它棋子),而且線的轉折次數不超過兩次,那麼這兩個棋子就可以在棋盤上消去。不好意思,由於我以前沒有玩過連連看,諮詢了同學的意見,連線不能從外面繞過去的,但事實上這是錯的。現在已經釀成大禍,就只能將錯就錯了,連線不能從外圍繞過。
玩家鼠標先後點擊兩塊棋子,試圖將他們消去,然後遊戲的後臺判斷這兩個方格能不能消去。現在你的任務就是寫這個後臺程序。
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時,輸入結束。
注意:詢問之間無先後關係,都是針對當前狀態的!
Output:
每一組輸入數據對應一行輸出。如果能消去則輸出"YES",不能則輸出"NO"。
Sample Input:
Sample Output:
思路分析:
這道題沒多少要求,只要求能有地方能走,並且只能走在數字爲0的地方,並且轉向不能超過2,這裏要防止幾點。一:如果所給的初始位置與終點位置都是0,不滿足條件。二:如果所給的初始位置和終點位置都一樣,也不滿足條件。三:如果給的位置過大過小,不滿足條件,退
四:剛好轉向爲2次,但位置不是終點也不滿足條件。五:轉向超過2次的都不滿足條件。
AC代碼:
用時:9006ms(第一次這麼長,要剪枝了)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string.h>
using namespace std;
int map[1100][1100];//記錄地圖位置
int Map[1100][1100];//標記位置是否走過
int b,c,e;
int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};//方向變量
int x2,y2,x3,y3;//初始位置與終點位置
int flag;//標記是否能走到 終點
int LemonJudge(int x,int y)//判斷位置與邊界
{
if(x<=0 || y<=0 || x>b || y>c || Map[x][y])
{
return 1;
}
return 0;
}
void LemonScanf()//輸入地圖
{
int d,g;
for(d=1;d<=b;d++)
{
for(g=1;g<=c;g++)
{
scanf("%d",&map[d][g]);
}
}
}
void LemonDFS(int x1,int y1,int n,int turn)
{
int x,y,i;
if(turn>2 || flag)//如果轉向大於2或者已經達到目的
return;
if(x1==x2 && y1==y2 && turn<=2)//如果轉向小於或等於2,並且走到終點,就標記成功
{
flag=1;
return;
}
for(i=0;i<4;i++)
{
x=x1+dir[i][0];
y=y1+dir[i][1];
if(LemonJudge(x,y))
continue;
if(map[x][y]==0 || (x==x2&& y==y2))//這裏要多判斷一下這個位置
{
Map[x][y]=1;
if(n==-1 || n==i)
{
LemonDFS(x,y,i,turn);
}
else
{
LemonDFS(x,y,i,turn+1);
}
if(flag)//剪枝,縮短時間
return;
else
Map[x][y]=0;
}
}
return;
}
int main()
{
while(scanf("%d %d",&b,&c)!=EOF)
{
if(b==0 && c==0)break;
memset(map,0,sizeof(map));
LemonScanf();
cin >> e;
while(e--)
{
cin >> x3 >> y3 >> x2 >> y2;
flag=0;//標記是否能走到
if(map[x3][y3]!=map[x2][y2] || map[x3][y3]==0 || map[x2][y2]==0 && (x2==x3 && y2==y3))
{
flag=0;
}
else
{
memset(Map,0,sizeof(Map));
LemonDFS(x3,y3,-1,0);
}
if (flag)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
}
return 0;
}