给定你每场比赛参加的账号,判断最少有多少个人在使用账号。
一个人一场比赛只用一个账号,一个账号只可以属于一个人。
则对每个账号分情况:
1.三场全都参加
2.只参加了12/13/23
3.只参加了1/2/3
4.没参加过
答案ans = 0
则没参加过的直接忽略掉,三场全参加的肯定确定了一个人 ans+=全参加
之后,只参加12的可以和只参加3的匹配 ans += min(12,3)
同理 13与2,23与1匹配
匹配完后要减去匹配的数目 12 -= min(12,3) 3 -= min(12,3)
13,2,23,1同理
还要考虑到只参加1,只参加2,只参加3的三个可以匹配在一起 ans+=max(1,2,3)
剩下的就无法匹配了 ans+=12+23+13
k=1或2时简单跳过
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 50;
int m[4] = {0};
int a[4][maxn] = {0};
int map[3][maxn] = {0};
int main()
{
int n, k;
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> k;
for(int i = 0; i < k; i++)
{
cin >> m[i];
for(int j = 0; j < m[i]; j++)
{
cin >> a[i][j];
map[i][a[i][j]] = 1;
}
}
if(k == 1)
{
cout << m[0] << endl;
return 0;
}
if(k == 2)
{
int un = 0;
for(int i = 0; i < m[1]; i++)
{
if(map[1][a[1][i]] == 1)
un++;
}
int ans = un + max(m[1] - un, m[0] - un);
cout << ans << endl;
return 0;
}
int quan = 0;
int cnt12 = 0, cnt13 = 0, cnt23 = 0;
int cnt1 = 0, cnt2 = 0, cnt3 = 0;
for(int j = 1; j <= n; j++)
{
if(map[0][j] && map[1][j] && map[2][j]) quan++;
if(map[0][j] && map[1][j] && !map[2][j]) cnt12++;
if(map[0][j] && !map[1][j] && map[2][j]) cnt13++;
if(!map[0][j] && map[1][j] && map[2][j]) cnt23++;
if(map[0][j] && !map[1][j] && !map[2][j]) cnt1++;
if(!map[0][j] && map[1][j] && !map[2][j]) cnt2++;
if(!map[0][j] && !map[1][j] && map[2][j]) cnt3++;
}
int ans = 0;
ans += quan;
if(cnt12 >= cnt3)
{
ans += cnt3;
cnt12 -= cnt3;
cnt3 = 0;
}
else
{
ans += cnt12;
cnt3 -= cnt12;
cnt12 = 0;
}
if(cnt13 >= cnt2)
{
ans += cnt2;
cnt13 -= cnt2;
cnt2 = 0;
}
else
{
ans += cnt13;
cnt2 -= cnt13;
cnt13 = 0;
}
if(cnt23 >= cnt1)
{
ans += cnt1;
cnt23 -= cnt1;
cnt1 = 0;
}
else
{
ans += cnt23;
cnt1 -= cnt23;
cnt23 = 0;
}
ans += cnt12 + cnt23 + cnt13 + max(max(cnt1, cnt2), cnt3);
cout << ans << endl;
return 0;
}