ZCMU—1949

xiaoxiao2021-02-28  126

1949: #6030. 「雅礼集训 2017 Day1」矩阵

Time Limit: 1 Sec   Memory Limit: 256 MB Submit: 24   Solved: 10 [ Submit][ Status][ Web Board]

Description

有一个 n×n n \times nn×n 的矩阵,每个位置 (i,j) (i, j)(i,j) 如果是.表示为白色,如果是#表示为黑色。

初始时,每个位置可以是黑色或白色的,(i,j) (i, j)(i,j) 位置的值会作为 ai,j a_{i, j}ai,j 给你。

现在有一种操作,选择两个整数 i,j∈[1,n] i, j \in [1, n]i,j[1,n],记 (i,1),(i,2),…,(i,n) (i, 1), (i, 2), \ldots, (i, n)(i,1),(i,2),,(i,n) 的颜色为 C1,C2,…Cn C_1, C_2, \ldots C_nC1,C2,Cn,将 (1,j),(2,j),…,(n,j) (1, j), (2, j), \ldots, (n, j)(1,j),(2,j),,(n,j) 的颜色赋为 C1,C2,…,Cn C_1, C_2, \ldots, C_nC1,C2,,Cn

你的任务是将整个矩阵变成全黑,如果能够办到,输出最少步数,否则输出 −1 -11

Input

第一行一个整数 n nn。 接下来 n nn 行,每行 n nn 个字符表示整个矩阵。

Output

输出只有一行,一个整数表示答案。

Sample Input

2 #. .#

Sample Output

3

HINT

对于 30% 30\%30% 的数据,n≤4 n \leq 4n4; 对于另外 20% 20\%20% 的数据,满足每一列都至少有一个黑色的格子; 对于 100% 100\%100% 的数据,1≤n≤1000 1 \leq n \leq 10001n1000

【分析】

首先可以发现一点,只要这个图中存在黑点,那么一定存在操作能使这个图变成全黑,所以只有图中不存在黑点的时候答案才是-1。 在考虑完-1之后,需要考虑的就是在一定存在答案的情况下,怎么判断最优解, 首先我们可以想到,要使得整个图都变成黑色的,那么模拟一下可以发现,不管如何操作,不管是否优先把某一行填满,中途总会有一行先变成黑色,当存在一行全是黑色的时候,后面的步骤就是用这一行依次去填满还没有满的每一列。 对于每一列,最少用一步才能让这一列都变成黑色, 所以我们考虑优先把某一行填满,剩下的步骤就是用这一行去填满所有未满的列了。 对填满某一行需要的步骤,就是这行中白点的数量,如果这行中没有白点,或者不存在某一种操作能让这一行中多出一个黑点,也就是对当前i行没有i列存在黑点,就需要多一步 【代码】 #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; char a[1100][1100]; int vis[1100]={0}; int main() { int n;scanf("%d",&n); for (int i=0;i<n;i++) scanf("%s",a[i]); int flag=1; int ans=0; for (int i=0;i<n;i++) { int t=0; for (int j=0;j<n;j++) { if (a[i][j]=='#') flag=0; if (a[j][i]=='.') t=1; if (a[j][i]=='#') vis[i]=1; } ans+=t; } if (flag){printf("-1\n");return 0;} int sum=0x3f3f3f3f; for (int i=0;i<n;i++) { int t=0; for (int j=0;j<n;j++) if (a[i][j]=='.') t++; if (t==n||!vis[i]) t++; sum=min(sum,t); } printf("%d\n",ans+sum); return 0; }
转载请注明原文地址: https://www.6miu.com/read-69823.html

最新回复(0)