2 条题解
-
0
这题差不多 分钟就想出来了,但是有个细节问题调了一会。
首先要想达成全黑你就得至少保证一行全黑。那么问题转化为对于每一行,将其转为全黑的最小次数。
那如何将一行的每个白色格子转化为黑色呢?
考虑只管这一行是不是全黑,对于格子 ,它可以由任意一行的第 个格子通过操作覆盖为该格子的颜色。那么只要第 列出现黑色格子,我们就可以在 次操作内将其变成黑色。这个记为 操作。
那如果第 列不存在黑色格子呢?
考虑对于 行的每一个第 个格子都执行一次上面的查找,不难发现:只要整个网格中存在一个格子为黑色,我们就可以在 次操作内使指定的任意一列都能有一个黑色格子。这个记为 操作。
这样就顺便把无解条件也求出来了。
而且,对于第 行的每个格子,都只会被第 列有没有黑色格子所影响,所以 操作对整行都有贡献,我们就只需要进行一次 操作了。(我一开始没发现然后每个 操作都执行一次 操作结果居然拿了 分)
另外一行全黑每次操作会使一列全黑,但是如果这一列本身全黑就不需要操作了,我们需要单独计算全黑的列数量并减去他们。
好了说完这么多就差不多了。
#include<bits/stdc++.h> using namespace std; #define int long long const int N=1010; char a[N][N];int b[N],c[N],d[N]; signed main() { int n;cin>>n; for(int i=1;i<=n;i++)scanf("%s",a[i]+1); int bk=1; for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)if(a[i][j]=='#'){bk=0;break;} if(bk){cout<<-1;return 0;} for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)b[j]|=a[i][j]=='#'; for(int i=1;i<=n;i++) { int bbk=0; for(int j=1;j<=n;j++)if(a[i][j]!='#') { d[i]++; bbk=1; } if(bbk&&!b[i])d[i]++; } int sum=0,ans=1e18; for(int i=1;i<=n;i++)if(b[i]==n)sum++; for(int i=1;i<=n;i++) ans=min(ans,d[i]+n-sum); cout<<ans<<'\n'; return 0; }
- 1
信息
- ID
- 10089
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 9
- 标签
- 递交数
- 13
- 已通过
- 3
- 上传者
