日常训练 矩阵
2017-03-29 19:16
169 查看
_题意简述:给出一个由黑白构成的n∗n矩阵,’#’表示黑,’.’表示白,有一种操作,选择两个整数i,j∈[1,n],记(i,1),(i,2),(i,3)...(i,n)的颜色为c1,c2,c3...cn,将(1,j),(2,j),(3,j)...(n,j)的颜色赋为c1,c2,c3...cn。任务是求出使矩阵全变黑的最小步数,若不存在则输出”-1”。(n≤1000)
考虑先将一行染成全黑再那这一行去一列一列地染整个矩阵。对于第i行如果有第j列为白色,需要用第i列有黑色的一行去染第j列,如果没有第i列的一行就要随便拿一个有黑色的一行染第i列,这样就要多一步。染完一行后要染的列是一开始没有全黑的列,因为之前在这一行全黑之前是没有一列能被后来染成黑色的。无解情况只可能是全白。
考虑先将一行染成全黑再那这一行去一列一列地染整个矩阵。对于第i行如果有第j列为白色,需要用第i列有黑色的一行去染第j列,如果没有第i列的一行就要随便拿一个有黑色的一行染第i列,这样就要多一步。染完一行后要染的列是一开始没有全黑的列,因为之前在这一行全黑之前是没有一列能被后来染成黑色的。无解情况只可能是全白。
#include<bits/stdc++.h> const int N = 1050; int n,a ,sum ,need ; bool exs ; char ch ; void greed_is_good(){ for (int i=1; i<=n; i++) for (int j=1; j<=n; j++) if (a[i][j] == 1) exs[j] = 1, sum[j]++; else need[i]++; for (int i=1; i<=n; i++) if (!exs[i]) need[i]++; int min = n + 1; for (int i=1; i<=n; i++) min = std::min(min,need[i]); if (min == n + 1){printf("-1\n"); return;} int ans = n + min; for (int i=1; i<=n; i++) if (sum[i] == n) ans--; printf("%d\n",ans); return; } int main(){ freopen("matrix.in","r",stdin); freopen("matrix.out","w",stdout); scanf("%d",&n); for (int i=1; i<=n; i++){ scanf("%s",ch + 1); for (int j=1; j<=n; j++) a[i][j] = ch[j] == '#'; } greed_is_good(); return 0; }
相关文章推荐
- 日常训练 20170531 矩阵
- 算法训练 矩阵乘法
- [日常训练] 独立集
- 【ShancoLove】带你看蓝桥杯——算法训练 矩阵乘法
- 日常训练 Idiot 的集合
- 蓝桥杯 算法训练 矩阵乘法
- 蓝桥杯_算法训练_矩阵乘法
- 日常训练 20170622 数字游戏
- 日常训练小结
- [日常训练] God Knows
- [日常训练] 树上的游戏
- 蓝桥杯--算法训练矩阵乘法
- [日常训练] CZA的蛋糕
- [日常训练] 分割田地
- 日常训练 20170605 MediumProblem
- 《算法竞赛-训练指南》第一章-1.24_pre二维矩阵中的最小连续矩阵和
- 【日常学习】codevs1287 矩阵乘法题解
- 日常训练20161013 括号表达式
- 日常训练20161014 成绩调研
- 蓝桥杯 算法训练 矩阵乘法