2020年第十八届绍兴市少儿信息学竞赛复赛试题粉刷匠题解
题解:
这一道题用传统方法很难做哦,光开二维数组就不行了,刚看到这道题时我真的很无语哦哦,所以用二维数组来存储直接out
这题的问题无非就是2个:
1.二维数组开不了。
2.二维循环用不了
到这里估计劝退了很多人了吧
so~~~该干嘛呢???
真相只有一个!!!
好的欢迎回来。
开启思维环节。
因为n,m,k都有10^6
所以我们只能开一个1~k的循环(如下)
for(int i=1;i<=k;i++){
}
在这个循环内操作 (输入部分我就不讲了)
废话太多!!!
emm我们可以用逆向思维 这样就不会局限了
so ~~你知道了吗??
for(int i=k;i>=1;i--){
}
倒着来
这样就不用考虑覆盖的问题了(但是这一行是否涂过还要看,所以要开二个标记的数组(行列))
并统计行列的个数。
设sum为蓝格总数
if->蓝色:
if->行:->y行标记,行数++,sum=sum+m-列数
if->列:->y列标记,列数++,sum=sum+n-行数
温馨提示:
用过的行列直接continue。
代码:
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int x[N],y[N],z[N],vh[N],vl[N];
int main(){
long long n,m,k,h=0,l=0;
long long sum=0;
scanf("%ld%ld%ld",&n,&m,&k);
for(int i=1;i<=k;i++){
scanf("%d%d%d",&x[i],&y[i],&z[i]);
}
for(int i=k;i>=1;i--){
if(x[i]==0&&vh[y[i]]==1) continue;
if(x[i]==1&&vl[y[i]]==1) continue;//用过了
if(z[i]==0){//红色
if(x[i]==0){//行
h++;//行增加
vh[y[i]]=1;//标记
}else if(x[i]==1){
l++;//列
vl[y[i]]=1;
}
}else{//蓝色
if(x[i]==0){
h++;
vh[y[i]]=1;
sum=sum+m-l;
}else if(x[i]==1){
l++;
vl[y[i]]=1;
sum=sum+n-h;
}
}
}
printf("%ld",sum);
return 0;
}