生活随笔
收集整理的這篇文章主要介紹了
P1141 01迷宫(BFS+记忆化)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
https://www.luogu.org/problemnew/show/P1141
題目描述
有一個僅由數字0與1組成的n×n格迷宮。若你位于一格0上,那么你可以移動到相鄰4格中的某一格1上,同樣若你位于一格1上,那么你可以移動到相鄰4格中的某一格0上。
你的任務是:對于給定的迷宮,詢問從某一格開始能移動到多少個格子(包含自身)。
輸入輸出格式
輸入格式:
第1行為兩個正整數n,m。
下面n行,每行n個字符,字符只可能是0或者1,字符之間沒有空格。
接下來m行,每行2個用空格分隔的正整數i,j,對應了迷宮中第i行第j列的一個格子,詢問從這一格開始能移動到多少格。
輸出格式:
m行,對于每個詢問輸出相應答案。
輸入輸出樣例
輸入樣例#1:
2 2
01
10
1 1
2 2
輸出樣例#1:
4
4
說明
所有格子互相可達。
對于20%的數據,n≤10;
對于40%的數據,n≤50;
對于50%的數據,m≤5;
對于60%的數據,n≤100,m≤100;
對于100%的數據,n≤1000,m≤100000。
Ac_code:
/*
詢問次數特別多,數據比較大,考慮用BFS+記憶化搜索:
同一塊連通塊能抵達的格子是一樣的,所以為每一塊連通塊標號,
同一塊連通塊上的點屬于唯一的一個標號。然后記錄每塊連通塊上格子總數,
那么詢問的時候就直接可以根據詢問點所屬的連通塊的標號直接輸出ans;
*/
#include <iostream>
#include <stdio.h>
#define MAXN 1000005
using namespace std
;
char a
[1005][1005];
bool vis
[1005][1005];
int p
[MAXN
];
int ans
[MAXN
];
int n
,m
,tno
;
int step
[4][2]= {-1,0,1,0,0,-1,0,1};
struct point
{int x
;int y
;
} s
,que
[MAXN
];
bool
check(point k
,point tp
)
{if(a
[k
.x
][k
.y
]=='1'){if(tp
.x
>0&&tp
.x
<=n
&&tp
.y
>0&&tp
.y
<=n
&&!vis
[tp
.x
][tp
.y
]&&a
[tp
.x
][tp
.y
]=='0'){return true
;}return false
;}else{if(tp
.x
>0&&tp
.x
<=n
&&tp
.y
>0&&tp
.y
<=n
&&!vis
[tp
.x
][tp
.y
]&&a
[tp
.x
][tp
.y
]=='1'){return true
;}return false
;}
}
void BFS(point s
)
{int head
= 0,tail
= 0;que
[tail
++] = s
;vis
[s
.x
][s
.y
] = true
;int u
= (s
.x
-1)*n
+ s
.y
;p
[u
] = tno
;int cnt
= 0;while(head
< tail
){point k
= que
[head
];cnt
++;head
++;point tp
;for(int i
= 0; i
< 4; i
++){tp
.x
= k
.x
+ step
[i
][0];tp
.y
= k
.y
+ step
[i
][1];if(check(k
,tp
)){vis
[tp
.x
][tp
.y
] = true
;u
= (tp
.x
-1)*n
+ tp
.y
;p
[u
] = tno
;que
[tail
++] = tp
;}}}ans
[tno
] = cnt
;
}
int main()
{cin
>>n
>>m
;tno
= 0;for(int i
= 1; i
<= n
; i
++){for(int j
= 1; j
<= n
; j
++){scanf(" %c",&a
[i
][j
]);}}for(int i
= 1; i
<= n
; i
++){for(int j
= 1; j
<= n
; j
++){if(!vis
[i
][j
]){s
.x
= i
;s
.y
= j
;++tno
;BFS(s
);}}}while(m
--){int x
,y
;cin
>>x
>>y
;int pos
= (x
-1)*n
+ y
;cout
<<ans
[p
[pos
]]<<endl
;}return 0;
}
總結
以上是生活随笔為你收集整理的P1141 01迷宫(BFS+记忆化)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。