https://codeforces.com/problemset/problem/1579/C
题目大意:
给出 n,m,k,给出一个大小为 nm 的矩形。矩形仅包含 " * " 和 " . "。需要你用任意个仅包含 " * " 的开口向上 v 形结构,两边斜率为1,且边长严格大于 k(包含交点),来包含所有矩形的 " * "。
思路
用 st(i,j) 表示第 i 第 j 列有没有被涵盖。
暴力枚举每一个点作为 "V" 的交点,尽可能地延伸,即尽量地去找更长的满足条件的边,如果长度小于 k 就找到不为 " * " 的点,就不更新,否则就一直往上找,不断地更新 vis 数组。最后判断所有需涵盖是否全部涵盖就行了。
代码实现:
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(0);
char a[25][25], ch;
bool st[25][25];
int n, m, k, x;
int check1(int x, int y)
{
int s = -1;
while(x && y && a[x][y]) -- y, -- x, ++ s;
return s;
}
int check2(int x, int y)
{
int s = -1;
while(x && y <= m && a[x][y]) -- x, ++ y, ++ s;
return s;
}
void color1(int x, int y, int z)
{
st[x][y] = 1;
while(z --) st[--x][--y] = 1;
}
void color2(int x, int y, int z)
{
while(z --) st[--x][++y] = 1;
}
void solve()
{
memset(st, 0, sizeof st);
cin >> n >> m >> k;
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= m; j ++)
{
cin >> ch;
if(ch == '*') a[i][j] = 1;
else a[i][j] = 0;
}
}
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= m; j ++)
{
if( (x = min(check1(i,j), check2(i,j))) >= k ) color1(i, j, x),color2(i, j, x);
}
}
for (int i = 1; i <= n; i ++ )
{
for(int j = 1; j <= m; j ++)
{
if(a[i][j] && !st[i][j])
{
cout << "NO" << endl; return;
}
}
}
cout << "YES" << endl;
}
int main()
{
IOS
int T = 1;
cin >> T;
while(T --)
{
solve();
}
return 0;
}