2020 CCPC Wannafly Winter Camp Day5
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+6;
int a[maxn][4]={0};
int book[maxn]={0};
int last[maxn]={0};
int main()
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=k;i++)
{
int m;
scanf("%d",&m);
for(int j=1;j<=n;j++) book[j]=0;
while(m--)
{
int tmp;
scanf("%d",&tmp);
if(book[tmp]==1) continue;
book[tmp]=1;
a[tmp][i]++;
}
}
int res=0;
if(k==1){
for(int i=1;i<=n;i++) if(a[i][1]) res++;
cout<<res<<endl;
return 0;
}
int tmp[3]={0};
if(k==2){
for(int i=1;i<=n;i++){
if(a[i][1]+a[i][2]>1){
res++;
}
if(a[i][1]+a[i][2]==1){
if(a[i][1]) tmp[1]++;
else tmp[2]++;
}
}
cout<<(res+max(tmp[1],tmp[2]))<<endl;
return 0;
}
if(k==3){
int cnt1=0,cnt2=0,cnt3=0,cnt12=0,cnt13=0,cnt23=0;
for(int i=1;i<=n;i++){
if(a[i][1]+a[i][2]+a[i][3]>2){
res++;
}
if(a[i][1]+a[i][2]+a[i][3]==1||a[i][1]+a[i][2]+a[i][3]==2){
if(a[i][1]&&a[i][2]&&!a[i][3]){
cnt12++;
}
if(!a[i][1]&&!a[i][2]&&a[i][3]){
cnt3++;
}
if(a[i][1]&&!a[i][2]&&a[i][3]){
cnt13++;
}
if(!a[i][1]&&a[i][2]&&a[i][3]){
cnt23++;
}
if(a[i][1]&&!a[i][2]&&!a[i][3]){
cnt1++;
}
if(!a[i][1]&&a[i][2]&&!a[i][3]){
cnt2++;
}
}
}
if(cnt12>cnt3){
cnt12-=cnt3;
res+=cnt3;
cnt3=0;
}
else{
cnt3-=cnt12;
res+=cnt12;
cnt12=0;
}
if(cnt13>cnt2){
cnt13-=cnt2;
res+=cnt2;
cnt2=0;
}
else{
cnt2-=cnt13;
res+=cnt13;
cnt13=0;
}
if(cnt23>cnt1){
cnt23-=cnt1;
res+=cnt1;
cnt1=0;
}
else{
cnt1-=cnt23;
res+=cnt23;
cnt23=0;
}
cout<<res+cnt12 + cnt13 + cnt23 + max(max(cnt1, cnt2), cnt3)<<endl; //-->正确答案;
//cnt12只能和固定的cnt3匹配,cnt23和cnt13同理;
//res+(cnt12 + cnt13 + cnt23)的原因:比如cnt12和cnt3成功匹配了,但是res3还有溢出的部分未被匹配 就比如:
// 2
// 2
// 0
//这组例子cnt12还有一组,但是cnt3已经被匹配完成,所有res还得加上多出来的这组cnt12;
//res加( max(max(cnt1, cnt2), cnt3))的原因: cnt12已经与cnt3匹配完了但是cnt1和cnt2和cnt3之间可能还有匹配;即3次比赛出现的账号次数都是1之间的匹配;这时候取3个数之间最大值即可;例子:
// 1 5
// 2
// 3
//这个例子中的各个账号只出现了1次cnt1=2,cnt2=1,cnt3=1; 取他们的max就是答案;
}
return 0;
}