题目传送门CodeForces - 1194B
题目大意:
- 给你一些图,含有一些可能残缺的cross
- 每补上一个残缺的小块,都需要花费1min的成本
- 你需要求出最小成本,使其至少包含一个cross
- 输入中字符 . 代表未涂方块,字符 * 代表涂色方块
下面是cross的一些要求:
//十字架所在行和列,需要全部图满
在5✖5的图中,只有四个crosses(1,3) (1,5) (2,3) (2,5)
剩下三个图都不包含cross
解题思路:
- 在读入的时候,存下每行字符 . 的个数
- 遍历存下来的图,计算每列字符 . 的个数,并更新答案
代码实现:
#include<bits/stdc++.h>
using namespace std;
#define FOR(i,j,k) for(int i=j; i<k; ++i)
#define FREIN() freopen("in.txt","r",stdin)
#define FREON() freopen("out.txt","w",stdout)
typedef long long LL;
const int maxn = 100 + 5;
int n, m;
string mp[50005];
int rq[50005];
int main() {
ios::sync_with_stdio(false);
int q;
cin >> q;
while(q--) {
cin >> n >> m;
for(int i = 1; i <= n; i++) {
cin >> mp[i];
mp[i] = '$' + mp[i];
rq[i] = 0;
for(int j = 1; j <= m; j++) { //存下每行的'.'的个数
if(mp[i][j] == '.') {
rq[i]++;
}
}
}
int ans = n * m;
for(int j = 1; j <= m; j++) {
int cq = 0;
for(int i = 1; i <= n; i++) { //计算每列'.'的个数
if(mp[i][j] == '.') {
cq++;
}
}
for(int i = 1; i <= n; i++) {
ans = min(ans, rq[i] + cq - (mp[i][j] == '.'));
}
}
cout << ans << endl;
}
}