题目链接
题目大意
有
k
组人,第
问是否存在一种就座方案,使得不存在不同组的人坐在相邻的位置。
分析
这是Round #428 (Div.2)的B题,当时比赛的时候是通过的,赛后被Hack掉了(新增数据见注释)。。。自己想的情况还是不够全面。
显然这是一道贪心题。
- 首先我们尽可能的让同一组的4个人去坐四人座
- 然后尽可能让同一组的2个人去坐两人座
此时考虑剩余的4人座,有以下几种就座情况:
{AAA_} {AA_B} {A__B}
前两种情况可以归结为,安排同一组的两个人坐4人座,还能有一个单人座给任一组的人坐,第三种情况为安排1个人座4人座,也可以安排另一个组的人来坐。因此,我们先尽量安排2个人坐剩余的4人座,每坐一组相当于多出来单人座
- 如果还有剩余的4人座,就安排1个人去4人座,每坐一组也多出个单人座
- 让剩余的人尽可能去坐多出来的单人座
如果还有人剩余,也有2人座剩余,安排1组的1个人坐二人座
进行完这些操作后,如果还有人剩余则不存在方案,如果没人剩余则存在方案。
代码
#include <bits/stdc++.h>
using namespace std;
const double pi=4*atan(1.0);
int a[10010];
int main()
{
int n,k,i,num_2,num_4,temp;
bool flag;
scanf("%d%d",&n,&k);
for (i=1;i<=k;i++)
scanf("%d",&a[i]);
num_2=2*n;num_4=n;
for (i=1;i<=k;i++)
{
/**先尽可能让同一组的4个人坐4人座*/
while (a[i]>=4&&num_4)
{
a[i]-=4;
num_4--;
}
}
for (i=1;i<=k;i++)
{
/**接着尽可能让同一组的2个人坐2人座*/
while (a[i]>=2&&num_2)
{
num_2--;
a[i]-=2;
}
}
for (i=1;i<=k;i++)
{
while (a[i]==3&&num_4)
{
num_4--;
a[i]-=3;
}
}
/**temp表示4人座做两个同一组的人,留出单人座的数量*/
temp=0;
for (i=1;i<=k;i++)
{
while (a[i]==2&&num_4)
{
num_4--;
temp++;
a[i]-=2;
}
}
/*安排某一组的人坐4人座,多出一个万能单人座*/
for (i=1;i<=k;i++)
{
while (a[i]==1&&num_4)
{
a[i]--;
num_4--;
temp++;
}
}
/*安排人座万能单人座*/
for (i=1;i<=k;i++)
{
while (a[i]&&temp)
{
temp--;
a[i]--;
}
}
/*如果还有2人座剩余,就安排某一组的1个人去坐*/
for (i=1;i<=k;i++)
{
while (a[i]==1&&num_2)
{
a[i]--;
num_2--;
}
}
flag=true;
for (i=1;i<=k;i++)
if (a[i])
{
flag=false;
break;
}
if (flag) printf("YES\n");
else printf("NO\n");
return 0;
}
/*
1 4
1 1 2 2
2 7
2 2 2 2 2 2 2
*/