题意: 二分时间 枚举最小的填充时间
#include <bits/stdc++.h>
using namespace std;
const int MAXN = (int)5e2+10;
int n, m;
char mps[MAXN][MAXN];
bool vis[MAXN][MAXN];
int cnt[MAXN][MAXN];
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
struct node {
int x, y;
node(int _x=0, int _y=0):x(_x),y(_y){}
};
bool checkk(int x, int y, int t) {
if(cnt[x][y] && cnt[x][y]<=t) return false;
return x>=0&&y>=0&&x<n&&y<m&&mps[x][y]!='1'&&!vis[x][y];
}
bool check(int x) {
queue<node> que;
memset(vis, false, sizeof vis);
for(int i = 0; i < m; ++i) {
if((cnt[0][i]&&cnt[0][i]>x) || !cnt[0][i]) {
if(mps[0][i] != '1') {
que.push(node(0,i));
vis[0][i] = true;
}
}
}
while(!que.empty()) {
node tmp = que.front();
que.pop();
if(tmp.x == n-1)
return false;
for(int i = 0; i < 4; ++i) {
int xx = tmp.x+dx[i];
int yy = tmp.y+dy[i];
if(checkk(xx, yy, x)) {
que.push(node(xx, yy));
vis[xx][yy] = true;
}
}
}
return true;
}
int main() {
int T;
cin >> T;
while(T--) {
memset(mps, 0, sizeof mps);
memset(cnt, 0, sizeof cnt);
cin >> n >> m;
for(int i = 0; i < n; ++i)
cin >> mps[i];
int q;
cin >> q;
for(int i = 1; i <= q; ++i) {
int x, y;
cin >> x >> y;
cnt[x][y] = i;
}
int l = 0, r = q, ans = -1;
while(l <= r) {
int mid = l+(r-l)/2;
if(check(mid))
ans = mid, r = mid-1;
else
l = mid+1;
}
cout << ans << endl;
}
return 0;
}