Problem ID:1009 連連看
簡單題意:一個棋盤上放了若干個棋子,如果兩個相同(位置不同)的棋子能用一條線連起來,且轉折次數不超過2次,則可將其消去。給出棋盤和棋子,以及試圖消去的兩個棋子位置。如果能消去,輸出“YES”,如果不能,輸出“NO”。
解題思路形成過程:利用BFS進行搜索,符合要求的下一步共有3個要求:
①:連線必須在棋盤內,不能從外面繞出去;
②:下一個目標區域的沒有以任何方向走過,或者新的走法轉折次數更少;
③:此區域無棋子(如果找到了目標直接return返回)。
注意:如果選擇的兩個棋子類型不同,或其中任意一個位置沒有棋子,則須直接輸出“NO”。
感想: 一個不是太難的題,WA了16次………… 改了N久…… 最後才發現WA的原因是如果是該輸出“NO”,主函數裏的條件該寫成對應的-1 而不是0…… 反覆檢查居然沒有發現…………
還有就是中間有一個情況沒有考慮到…
一開始用的DFS,會超時,後來又改成BFS寫的。不過如果剪枝處理的比較好,DFS應該也可以。
第一次見識和學習了三維數組,挺好使。
注意條件的整合,以提高代碼效率。
無論如何…… 終於是AC了…
代碼:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
#define INF 10000
int cmap[1001][1001];
int mark[1001][1001][4];
int query[4];
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int n,m;
int BFS()
{
queue<int>s;
s.push(query[0]); //隊列中4個元素爲一組,分別是當前行(r),當前列(c),當前方向(state),當前轉折次數(cnt)。
s.push(query[1]);
s.push(-1);
s.push(-1);
while(!s.empty())
{
int r=s.front();
s.pop();
int c=s.front();
s.pop();
int state=s.front();
s.pop();
int cnt=s.front();
s.pop();
for(int i=0;i<4;++i){ //i也代表了移動的方向。i=0,1,2,3分別代表了上,下,左,右。
int t_cnt=cnt;
if(i!=state)
++t_cnt;
if(t_cnt>2)
continue;
if(r+dir[i][0]==query[2]&&c+dir[i][1]==query[3])
return 1;
if(r+dir[i][0]>=0&&r+dir[i][0]<n&&c+dir[i][1]>=0&&c+dir[i][1]<m)
if(mark[r+dir[i][0]][c+dir[i][1]][i]>t_cnt) //沒走過或者新的路徑轉折次數更少
if(cmap[r+dir[i][0]][c+dir[i][1]]==0){
// cout<<r<<' '<<c<<' '<<"go"<<endl;
s.push(r+dir[i][0]);
s.push(c+dir[i][1]);
s.push(i);
s.push(t_cnt);
mark[r+dir[i][0]][c+dir[i][1]][i]=t_cnt;
}
}
}
return -1;
}
int main()
{
freopen("1.txt","r",stdin);
while(1)
{
scanf("%d%d",&n,&m);
if(n==0)
return 0;
for(int i=0;i<n;++i)
for(int j=0;j<m;++j)
cin>>cmap[i][j];
int q;
scanf("%d",&q);
for(int i=0;i<q;++i){
scanf("%d%d%d%d",&query[0],&query[1],&query[2],&query[3]);
--query[0];
--query[1];
--query[2];
--query[3];
memset(mark,INF,sizeof(mark));//INF
if(cmap[query[0]][query[1]]!=cmap[query[2]][query[3]]||cmap[query[0]][query[1]]==0||cmap[query[2]][query[3]]==0||(query[0]==query[2]&&query[1]==query[3]))
printf("NO\n");
else if(BFS()==1)
printf("YES\n");
else if(BFS()==-1)
printf("NO\n");
}
}
}