PkU 1059(个人赛的一个水题 跪了)

时间:2022-09-10 15:50:25

1059:table

总时间限制: 
1000ms 
内存限制: 
65536kB
描述

Sths所在的学校里有一个神奇的房间,这个房间有A张边长为1的等边三角形桌子(图a)和B张边长为1的正方形桌子(图b),以及足够多的椅子。

这个教室主要用来提供给学生进行组队作业,一个小组可以从这个房间中选出一些桌子来拼在一起供他们使用,但是要求这些桌子拼接起来的部分一定是边和边完整的契合(例如下图中图c,图d为非法,图e为合法),且一个拼起来的“桌子块”周围能坐下的最多的人数为这个“桌子块”的周长。

PkU 1059(个人赛的一个水题 跪了)

现在告诉你申请教室的小组数N、每个小组的学生数SN以及A和B,请计算同时最多可以满足多少个小组的申请?


输入
一个测试点将包含多组输入,以EOF结束。
每组输入的第一行为三个整数N,A,B意义同题目描述。
每组输入的第二行为N个整数,其中第i个整数Si表示第i个小组的学生数。
1<=N<=10000,0<=A,B<=10^6,1<=Si<=10^6,输入数据组数小于等于10。
输出
对于每组输入,输出一个整数Ans,表示最多可以同时满足的小组数量。
样例输入
3 2 23 4 53 2 23 4 63 1 33 4 6
样例输出
323


题目意思不说了,多拿笔画画啊,竟然推了半天最后看了下数据,公式写的有问题。。。自己分类还是这么麻烦。
    题目地址:1059:table
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int p[10005];
int n,a,b;

int solve()
{
int pos=0;
int num=a+b;
while(1)
{
if(pos==n) break;
else if((num==1)&&(3*a<p[pos]&&4*b<p[pos])) break;
else if(num>1&&a+2*b+2<p[pos]) break;
else
{
int t=p[pos];
if(!(t&1))
{
if(t<=3&&a>=1) {a--,num--,pos++;}
else if(t<=4) {b--,num--,pos++;}
else
{
int tb=(t-2)/2,ta;
if(b>=tb)
{
b-=tb;
num-=tb;
pos++;
}
else
{
ta=t-2-2*b;
a-=ta;
b=0;
num=num-(ta+b);
pos++;
}
}
}
else
{
if(t<=3&&a>=1) {a--,num--,pos++;}
if(t<=4) {b--,num--,pos++;}
else
{
int tb=(t-3)/2,ta;
if(a>=1&&b>=tb)
{
a--,b-=tb;
num=num-(1+tb);
pos++;
}
else if(a==0)
{
tb++;
b-=tb;
num=num-tb;
pos++;
}
else
{
ta=t-2-b*2;
a-=ta;
b=0;
num=num-(ta+b);
pos++;
}
}
}
}
}

return pos;
}

int main()
{
int i;
while(cin>>n>>a>>b)
{
for(i=0;i<n;i++)
cin>>p[i];
sort(p,p+n);
cout<<solve()<<endl;
}
return 0;
}

/*
3 2 2
8 9 10
*/