Description
一桌人数超过两个大家才不会觉得无聊,给出每桌人数,问是否存在一种换座方案使得所有人都不会感到无聊,如果存在输出最少交换次数
Input
第一行一整数
n
表示桌子个数,之后输入
Output
如果存在方案使得所有人都不感到无聊则输出最少交换次数,否则输出 −1
Sample Input
5
1 2 2 4 3
Sample Output
2
Solution
主要是处理一人桌和两人桌,设其数量分别为 a,b
1.a≥b ,显然首先用一人桌去把两人桌的变合法,剩下的那些一人桌的三三组合(这样移动两次就可以解决三个人,否则每次移动至多解决一个人),最后剩下的一人桌有 0,1,2 三种情况。此时如果一人桌的数量不超过三人桌的数量,那么把一人桌移动到三人桌即可;否则如果有两个一人桌的话,此时三人桌至多一个,无法解决这两个一人桌,此时需要四人桌来解决,即四人桌出一个人和这两个人组成一个三人桌;否则如果有一个一人桌的话,此时没有三人桌,只能四人桌来解决,且至少需要两个四人桌一桌出一人来和这个落单的组成三人桌;以上条件都不满足则无解
2.a<b ,先用一人桌去解决一部分二人桌,然后二人桌三三组合(这样移动两次就可以解决三个二人桌,比从四人桌移动一人来解决一个二人桌更优),之后剩下的二人桌有 0,1,2 三种情况。如果只剩下一个二人桌,如果有四人桌,那么来一个人即可解决这个二人桌,如果没有三人桌则至少需要两个三人桌来放这两个人,否则无解;如果剩下两个二人桌,只需把这两个二人桌凑成一个四人桌即可
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=10;
int n,m[5];
int main()
{
while(~scanf("%d",&n))
{
memset(m,0,sizeof(m));
while(n--)
{
int a;
scanf("%d",&a);
m[a]++;
}
int ans=0;
if(m[1]>=m[2])
{
m[1]-=m[2],m[3]+=m[2],ans+=m[2],m[2]=0;
m[3]+=m[1]/3,ans+=m[1]/3*2,m[1]%=3;
if(m[1]<=m[3])ans+=m[1];
else if(m[4]&&m[1]==2)ans+=2;
else if(m[4]>=2&&m[1]==1)ans+=2;
else ans=-1;
}
else
{
m[2]-=m[1],m[3]+=m[1],ans+=m[1],m[1]=0;
m[3]+=m[2]/3*2,ans+=m[2]/3*2,m[2]%=3;
if(m[2]==1)
{
if(m[4])ans++;
else if(m[3]>=2)ans+=2;
else ans=-1;
}
else if(m[2]==2)ans+=2;
}
printf("%d\n",ans);
}
return 0;
}