HDU 1175 連連看

連連看

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 14418    Accepted Submission(s): 3778


spa

Problem Description
「連連看」相信不少人都玩過。沒玩過也不要緊,下面我給你們介紹一下游戲規則:在一個棋盤中,放了不少的棋子。若是某兩個相同的棋子,能夠經過一條線連起來(這條線不能通過其它棋子),並且線的轉折次數不超過兩次,那麼這兩個棋子就能夠在棋盤上消去。很差意思,因爲我之前沒有玩過連連看,諮詢了同窗的意見,連線不能從外面繞過去的,但事實上這是錯的。如今已經釀成大禍,就只能將錯就錯了,連線不能從外圍繞過。
玩家鼠標前後點擊兩塊棋子,試圖將他們消去,而後遊戲的後臺判斷這兩個方格能不能消去。如今你的任務就是寫這個後臺程序。
 

 

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
3 4
1 2 3 4
0 0 0 0
4 3 2 1
4
1 1 3 4
1 1 2 4
1 1 3 3
2 1 2 4
3 4
0 1 4 3
0 2 4 1
0 0 0 0
2
1 1 2 4
1 3 2 3
0 0
 

 

Sample Output
YES
NO
NO
NO
NO
YES
#include <stdio.h>

typedef struct
{
    int aim;
    int x;
    int y;
}Qu;
Qu Queue[1000005];//隊列
int Map[1005][1005];//數字矩陣
int Time[1005][1005];//到達某個位置的次數
int move[4][2]={0,1,-1,0,0,-1,1,0};
int x1,y1,x2,y2;
int m,n,t;

int BFS()
{
    int i;
    int I,J;
    int time;
    int rear,front;
    rear=front=-1;
    rear++;
    Time[x1][y1]=0;
    Queue[rear].aim=0;
    Queue[rear].x=x1;
    Queue[rear].y=y1;
    while(rear>front)
    {
        front++;
        //找到返回1
        if(Queue[front].x==x2 && Queue[front].y==y2)
        {
            return 1;
        }
        //四個方向搜索
        for(i=0;i<4;i++)
        {
            I=Queue[front].x+move[i][0];
            J=Queue[front].y+move[i][1];
            if((!Map[I][J] || I==x2 && J==y2) && I>0 && J>0 && I<=m && J<=n)
            {
                //開始的方向和如今的方向不一樣則次數加一
                if(Queue[front].aim && Queue[front].aim!=i+1)
                {
                    time=Time[Queue[front].x][Queue[front].y]+1;
                }
                else
                {
                    //!Queue[front].aim表明沒有轉彎
                    if(!Queue[front].aim || Queue[front].aim==i+1)
                    {
                        time=Time[Queue[front].x][Queue[front].y];
                    }
                }
                //若是當前到達某個數字的轉彎次數少於之前的次數,則將該數字的位置如隊列,並更新次數
                if(Time[I][J]>=time && time<3)
                {
                    rear++;
                    Queue[rear].aim=i+1;//方向爲當前的方向
                    Queue[rear].x=I;
                    Queue[rear].y=J;
                    Time[I][J]=time;//更新次數
                }
            }
        }
    }
    return 0;
}

int main()
{
    int i,j,k;
    while(1)
    {
        scanf("%d %d",&m,&n);
        if(!m && !n)
        {
            break;
        }
        for(i=1;i<=m;i++)
        {
            for(j=1;j<=n;j++)
            {
                scanf("%d",&Map[i][j]);
            }
        }
        scanf("%d",&t);
        for(i=0;i<t;i++)
        {
            for(j=1;j<=m;j++)
            {
                for(k=1;k<=n;k++)
                {
                    Time[j][k]=100000000;//次數初始化爲無窮大
                }
            }
            scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
            if(!Map[x1][y1] || !Map[x2][y2] || (Map[x1][y1]!=Map[x2][y2]))
            {
                printf("NO\n");
                continue;
            }
            if(BFS() || (x1==x2 && y1==y2))
            {
                printf("YES\n");
            }
            else
            {
                printf("NO\n");
            }
        }
    }
    return 0;
}
相關文章
相關標籤/搜索