codeforce 893B (模拟)

大意:有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;
} 




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值