题解:CF2090B Pushing Balls
洛谷CF2090B || CodeForces 2090 B
简要题意
对于一个
现给出网格的最终状态,判断其是否合法,即是否可以通过题目所述的方法达到此状态。
思路
对于每个有球的格子,球只可能从行首或列首推入,并由其他球推到该位置。因此其上所有的格子或其左所有的格子必有其一是被球填满的,以表明球是从此方向推入而来的。
因此,对于每个球,我们检查每个球上方所有的格子是否都为
为降低时间复杂度,可以先预处理出每个球的上方格子或左边格子是否皆为 r_pre 与 c_pre 中。
通过记录
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin >> t;
while (t--)
{
int n, m;
cin >> n >> m;
vector<string> a(n);
for (int i = 0; i < n; ++i) cin >> a[i];
vector<vector<bool>> c_pre(m, vector<bool>(n + 1, false));
vector<vector<bool>> r_pre(n, vector<bool>(m + 1, false));
for (int i = 0; i < n; ++i)
{
r_pre[i][0] = true;
for (int j = 1; j <= m; ++j) r_pre[i][j] = r_pre[i][j - 1] && (a[i][j - 1] == '1');
}
for (int j = 0; j < m; ++j)
{
c_pre[j][0] = true;
for (int i = 1; i <= n; ++i) c_pre[j][i] = c_pre[j][i - 1] && (a[i - 1][j] == '1');
}
bool flag = true;
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
if (a[i][j] == '1')
{
bool R = r_pre[i][j];
bool C = c_pre[j][i];
if (!R && !C)
{
flag = false;
goto end;
}
}
}
}
end:
cout << (flag ? "YES" : "NO") << '\n';
}
return 0;
}