大意:有n行座位,每行如下分布,共8个座位
现在有k组人,每组人数在1~10000 之间,要求给他们安排座位,并且使不同组的人不相邻;{1, 2}, {3, 4}, {4, 5}, {5, 6} or {7, 8}.被认为是相邻的座位
先处理中间的四连坐,再处理两遍的二连坐,
①让四连座坐大于等于4的和三的组数,如果有剩余,证明剩余组的人数小于3,在模拟分配一下;注意两个四连座可分配最多三个二人组;
②如果四连座没剩余,则只剩2的座位,模拟分配一下
自己的写法确实啰嗦,网上有代码length60-,Orz,但这个是自己想出来的,贴一下吧
#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
int a[200];
int main()
{
int n,sum,de,v,re,flag,three,one,two,nu_f,nu_tw,k,r,ans,minn;
while (scanf("%d%d",&k,&n)!=EOF)
{
sum=0;
flag=0;
three=two=one=nu_f=nu_tw=0;
for (int i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,a+n);
nu_tw=k*2;
nu_f=k;
for (int i=n-1;i>=0;i--)
{
if (a[i]!=0)
{
if (a[i]>=4)
{
if (nu_f>0)
{
r=a[i]/4;
if (r>nu_f)
{
a[i]-=4*nu_f;
nu_f=0;
}
else
{
nu_f-=r;
a[i]=a[i]%4;
}
}
}
if (a[i]==3&&nu_f>0)
{
nu_f--;
a[i]=0;
}
if (a[i]==1)
one++;
if (a[i]==2)
two++;
}
else
break;
}
if (nu_f!=0)
{
minn=min(two,one);
int mn=minn;
minn-=nu_f;
if (minn>=0)
{
two-=nu_f;
one-=nu_f;
if (one+two>nu_tw)
cout<<"NO"<<endl;
else
cout<<"YES"<<endl;
}
else
{
two-=mn;
one-=mn;
nu_f-=mn;
if (two==0)
{
if (nu_f*2+nu_tw<one)
cout<<"NO"<<endl;
else
cout<<"YES"<<endl;
}
else
{
int kk=nu_f/2;
kk=kk*3+nu_f%2;
nu_f=kk;
if (nu_f+nu_tw<two)
cout<<"NO"<<endl;
else
cout<<"YES"<<endl;
}
}
}
else
{
flag=0;
sort(a,a+n);
for (int i=n-1;i>=0;i--)
{
if (a[i]!=0)
{
if (a[i]>=2)
{
r=a[i]/2;
if (nu_tw>=r)
{
nu_tw-=r;
if (a[i]%2!=0)
{
if (nu_tw<=0)
{
flag=1;
break;
}
else
nu_tw-=1;
}
}
else
{
flag=1;
break;
}
}
else
{
if (nu_tw<=0)
{
flag=1;
break;
}
nu_tw--;
}
}
else
break;
}
if (flag)
cout<<"NO"<<endl;
else
cout<<"YES"<<endl;
}
}
return 0;
}