题目描述:
Q老师 得到一张 n 行 m 列的网格图,上面每一个格子要么是白色的要么是黑色的。
Q老师认为失去了 十字叉 的网格图莫得灵魂. 一个十字叉可以用一个数对 x 和 y 来表示, 其中 1 ≤ x ≤ n 并且 1 ≤ y ≤ m, 满足在第 x 行中的所有格子以及在第 y 列的 所有格子都是黑色的
例如下面这5个网格图里都包含十字叉
第四个图有四个十字叉,分别在 (1, 3), (1, 5), (3, 3) 和 (3, 5).
下面的图里没有十字叉
Q老师 得到了一桶黑颜料,他想为这个网格图注入灵魂。 Q老师 每分钟可以选择一个白色的格子并且把它涂黑。现在他想知道要完成这个工作,最少需要几分钟?
Input
第一行包含一个整数 q (1 ≤ q ≤ 5 * 10^4) — 表示测试组数
对于每组数据:
第一行有两个整数 n 和 m (1 ≤ n, m ≤ 5 * 10^4, n * m ≤ 4 * 10^5) — 表示网格图的行数和列数
接下来的 n 行中每一行包含 m 个字符 — ‘.’ 表示这个格子是白色的, ‘*’ 表示这个格子是黑色的
保证 q 组数据中 n 的总和不超过 5 * 10^4, n*m 的总和不超过 4 * 10^5
Output
答案输出 q 行, 第 i 行包含一个整数 — 表示第 i 组数据的答案
Example
Input
Output
0
0
0
0
0
4
1
1
2
题目分析:
本题的数据非常大,所以靠扫描一遍是不行的,而且还有个问题就是数组范围太大了,本地编译器都抛出warning,但是他的个数(n*m)是比较小的,也就是说输入的样例可能是横坐标小纵坐标大的数组或者横坐标大纵坐标小的数组,这样也就意味着并不需要预留那么大的数组空间,所以我们就需要压缩,把二维数组压缩为一维数组,这样空间复杂度瞬间下降。
char a[400010]={0};
这样我们按照行进行压缩,输入的时候一行一行的输入,然后进行一行的偏移,这里就体现scanf的好处了,因为他输入的时候要带着地址,而数组符号刚好就是起始地址,所以加上偏移量就是偏移地址了。
for(int i=0;i<n;i++)
{
scanf("%s",a+i*m);
}
然后他要找的是需要填充多少,而不是具体填充哪里。这样就意味着既然不能一个一个扫描,那就扫描行和列,记录下每行每列有多少个白格子毕竟填充就是看哪一行哪一列白格子少。当然这里扫描的时候注意偏移量,扫描列就从im到(i+1)m,这就是一样中m个数,扫描列的时候从i(注意不是1,别看错了)到nm,每次前进m个单位。
for(int i=0;i<n;i++)
{
row[i]=0;
for(int j=i*m;j<(i+1)*m;j++)
{
if(a[j]=='.')
{
row[i]++;
}
}
}
for(int i=0;i<m;i++)
{
col[i]=0;
for(int j=i;j<n*m;j=j+m)
{
if(a[j]=='.')
{
col[i]++;
}
}
}
然后就是看谁的白格子少了,当然这里要考虑特殊情况,就是一行+一列的时候可能交叉点重复计算,所以如果交叉点也是白格子就要把重复的删掉。
int ans=1919810;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
int sum=col[j]+row[i];
if(a[i*m+j]=='.')
{
sum--;
}
ans=min(ans,sum);
}
}
代码如下:
#include<iostream>
using namespace std;
char a[400010]={0};
int row[400010]={0};
int col[400010]={0};
int main()
{
int q;
cin>>q;
while(q--)
{
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++)
{
scanf("%s",a+i*m);
}
for(int i=0;i<n;i++)
{
row[i]=0;
for(int j=i*m;j<(i+1)*m;j++)
{
if(a[j]=='.')
{
row[i]++;
}
}
}
for(int i=0;i<m;i++)
{
col[i]=0;
for(int j=i;j<n*m;j=j+m)
{
if(a[j]=='.')
{
col[i]++;
}
}
}
int ans=1919810;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
int sum=col[j]+row[i];
if(a[i*m+j]=='.')
{
sum--;
}
ans=min(ans,sum);
}
}
cout<<ans<<endl;
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)