有一个带有植物的田地 - 一个有N行(编号为1到N)和M列(编号为1到M)的网格;在其NM细胞中,K细胞含有植物,而其余的含有杂草。在这个网格之外,到处都是杂草。如果它们具有共同侧,则两个单元相邻。
您希望在现场构建栅栏,使得包含工厂的每个单元格具有以下条件:
有可能从这个细胞移动到包含植物的每个相邻细胞而不穿过任何围栏,不可能从这个细胞移动到任何含有杂草的细胞而不穿过任何围栏
输入:
输入的第一行包含一个整数T,表示测试用例的数量。下面是T测试用例的描述。每个测试用例的第一行包含三个以空格分隔的整数N,M和K.接下来是K行。这些行中的每一行包含两个空格分隔的整数r和c,表示行r和列c中的单元格包含植物。
#include <iostream>
#include<vector>
#include<queue>
using namespace std;
int main() {
// your code goes here
int t,n,m,i,j,k,flag=0;
int r[4] = {-1,1,0,0};
int c[4] = {0,0,-1,1};
cin>>t;
while(t--) {
int ans=0;
cin>>n>>m>>k;
vector < vector<int> > vec(n, vector<int>(m,0));
/* for(int z=0; z<k; z++) {
cin>>i>>j;
vec[i-1][j-1] = 1;
} */
queue<pair<int,int>> q;
for(i=0;i<n;i++) {
for(j=0;j<m;j++) {
if(vec[i][j] == 1) {
q.push(make_pair(i,j));
flag = 1;
break;
}
}
if(flag==1)
break;
}
while(!q.empty()) {
pair<int,int> p = q.front();
int a = p.first;
int b = p.second;
int x=0;
q.pop();
for(i=0;i<4;i++) {
for(j=0;j<4;j++) {
int rr = a + r[i];
int cc = b + c[j];
if(rr<0 || cc<0 || rr>=n || cc>=m || vec[rr][cc]==0)
continue;
else {
q.push(make_pair(rr,cc));
x++;
}
}
}
ans = ans + (4-x);
}
cout<<ans<<endl;
}
return 0;
}
如果我删除上面的注释,它会显示超时错误。我无法通过上述声明检测到问题。
假设用户为两对(6,7)和(7,7)设置1。
然后会发生以下情况:
因此,如果只有一对相邻的对,你的循环将不会终止(并且对于较大的群组,问题会更严重)。
如果你想避免这种情况,你可以在访问该字段后设置vec[rr][cc] = 0
;或者,您可以设置vec[rr][cc] = -1
(或任何其他不同于0和1的值),然后您可以区分:1,未访问0(但具有相同值),访问0(更改为-1)。但是,您需要调整支票:
if(0 <= rr && rr < n && 0 <= cc && cc < m && vec[rr][cc] == 1)
// ...
因为跳过== 0
将不再起作用(重新排序比较是没有必要的,但现在的方式它更接近数学方程0 <= rr <= n
,当然,这不能用C ++这样写)。