Description
Alice在玩一个游戏,她在一个m×n 的格子里,随机涂黑k个格子。然后她每次可以把一行或者一列的格子染成红色,但是这一行中不能有黑色的格子。 请问她最多能把多少个格子涂成红色?
Input
第一行是一个整数T(T≤100) ,表示样例的个数。 每个样例的第一行是m(1≤m≤100),n(1≤n≤100),k(0≤k≤m×n) 。 以后的k行,每行两个整数x(1≤x≤m),y(1≤y≤n) ,表示(x,y) 为黑色格子。
Output
每行输出一个样例的结果。
Sample Input
1
3 4 2
1 1
3 3
Sample Output
8
提示
解题思路:
解法一:可以发现这一行和这一列都有黑格子的或者本身就是黑格子的就不能涂红色,其他都可以。用bool的数组存放数据,然后利用规律直接暴力解决。
#include<bits/stdc++.h>
using namespace std;
bool b[101][101];
int m,n;
bool Color(int x, int y)
{
if(b[x][y] == false)
return false;
else
{
for(int i = 1; i <= n; i++)
{
if(b[x][i] == false)
{
for(int j = 1; j <= m; j++)
if(b[j][y] == false) return false;
}
}
}
return true;
}
int main()
{
memset(b, 1, sizeof(b));
int sum = 0;
int T;
int k;
cin>>T;
while(T--)
{
cin >> m >> n >> k;
for(int i = 0; i < k; i++)
{
int x, y;
cin>>x>>y;
b[x][y] = false;
}
for(int i = 1; i <= m; i++)
{
for(int j = 1; j <= n; j++)
if(Color(i, j))
sum++;
}
cout<<sum<<endl;
sum = 0;
memset(b, 1, sizeof(b));
}
return 0;
}
解法二:添加一行和一列作为额外空间,用来标记所有黑色格子所属的行和列,然后用[m × (没有标记的列数)] + [n × (没有标记的行数)] - [ (没有标记的列数) × (没有标记的行数)]即可。因为两者相乘再相加后重合部分加了两次,所以要减去一次。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int T;
int m,n,k;
cin >> T;
while(T--)
{
int a[102][102] = {0};//第0行第0列设置为额外空间
cin >> m >> n >> k;
int Cntm = 0,Cntn = 0;
for(int i = 0; i < k; i++)
{
int x,y;
cin >> x >> y;
a[x][0] = 1;//记录某行或某列被标记
a[0][y] = 1;
}
for(int i = 1; i < m+1; i++)
{
if(a[i][0] == 0)
Cntm++;
}
for(int i = 1; i < n+1; i++)
{
if(a[0][i] == 0)
Cntn++;
}
cout << m*Cntn+n*Cntm-Cntn*Cntm << endl;//公式计算
}
return 0;
}
解法三:直接n×m-(x的种类数)×(y的种类数)即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e3+5;
set<int>x,y;
int main()
{
int T;
cin>>T;
while(T--)
{
x.clear();
y.clear();
int m,n,k,a,b;
cin>>m>>n>>k;
for(int i=0; i<k; i++)
{
cin>>a>>b;
x.insert(a);
y.insert(b);
}
cout<<n*m-x.size()*y.size()<<endl;
}
return 0;
}