BZOJ 1034 [ZJOI2008]泡泡堂BNB

2017.12.13

题目大意

给你N个人,要和N个人比赛,如果你方人的权值大于他方人的权值那么你方得分+2,如果相等+1,小于则不加,问你可能得分的最大值和最小值。


这题一眼贪心!

之后就得出了错解x1:首先排序,之后从大到小枚举,对于每个人尝试消灭比他刚好小一点的人,如果不能那就尽量平手,如果连平手都平不了那就直接消灭最大的殉职以为后面的人创造机会。

看起来很有道理……但是对于一组数据"2 3"对"1 3",此时用以上方法得分为2,但是如果让3和3平手的话2也可以打败1,总得分为3.

具体做法很奇怪……每次考虑我最小的能不能把对面最小的干掉。之后考虑我最大的能不能把对面最大的干掉。如果都不能的话考虑牺牲最小的把最大的干掉。

我读入优化写错了啊……#摔

#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
#define N 100000
#define R register
int n,a[N+1],b[N+1],al,bl,ar,br,ansa,ansb;
inline char nc()
{
	static char buf[N],*p1,*p2;
	return p1==p2&&(p2=(p1=buf)+fread(buf,1,N,stdin),p1==p2)?EOF:*p1++;
}
inline int RI()
{
	R int ret=0;R char tmp=nc();
	while(!isdigit(tmp)) tmp=nc();
	while(isdigit(tmp)) ret=ret*10+(tmp^'0'),tmp=nc();
	return ret;
}
int main()
{
	n=RI();
	for(R int i=1;i<=n;++i) a[i]=RI();
	for(R int i=1;i<=n;++i) b[i]=RI();
	sort(a+1,a+n+1);
	sort(b+1,b+n+1);
	al=bl=1,ar=br=n;
	while(al<=ar)
	{
		if(a[al]>b[bl]) al++,bl++,ansa+=2;
		else if(a[ar]>b[br]) ar--,br--,ansa+=2;
		else
		{
			if(a[al]==b[br]) ansa++;
			al++,br--;
		}
	}
	al=bl=1,ar=br=n;
	while(al<=ar)
	{
		if(b[bl]>a[al]) bl++,al++,ansb+=2;
		else if(b[br]>a[ar]) br--,ar--,ansb+=2;
		else
		{
			if(b[bl]==a[ar]) ansb++;
			bl++,ar--;
		}
	}
	printf("%d %d",ansa,(n<<1)-ansb);
}