ACM-ICPC北京赛区2015 A hihoCoder 1249 Xiongnu's Land

看了大牛的代码才明白正确的解法是怎样的。一开始想的是只枚举快要到一半的那一部分,就是这个“快要”的判断要了我半条命,WA了N次。大牛的想法很犀利。

总结:对于这种问题,最好就是直接枚举所有情况,再在其他地方做优化保证不超时。

详细注释代码:

<span style="font-size:14px;">#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
typedef long long lld;
lld mark[1000010];
int main()
{
	int cas;
	scanf("%d",&cas);
	for(int cc=1;cc<=cas;cc++)
	{
		lld r;
		scanf("%lld",&r);
		lld total=0;
		int n;
		scanf("%d",&n);
		memset(mark,0,sizeof(mark));
		for(int i=0;i<n;i++)
		{
			lld l,t,w,h;
			scanf("%lld %lld %lld %lld",&l,&t,&w,&h);
			mark[l]+=h;   //对于[l,l+w]这一段区间,从l开始享有高 为 h 的高,从l+w开始不享有
			mark[l+w]-=h;   //所以mark[l+w] 要-=h,mark[l]是+=h; //这样有效的解决了重叠的问题。
			total+=h*w;
		}
		lld mls=r*r+1;   //卫青的面积,一开始全分给他
		lld mrs=0;     //霍去病的面积,一开始为0;
		lld ls,rs;      //用来维护他们两的面积
		ls=0;
		rs=total;
		lld hand=0;
		lld ans=0;
		for(int i=1;i<=r;i++)
		{
			hand+=mark[i-1];   //当前扫描的总面积
			ls+=hand;        //卫青的面积
			rs-=hand;          //霍去病的面积=总面积-卫青的面积
			if(ls < rs)          //如果卫青的面积 < 霍去病的面积,则不能更新
				continue;
			if(ls-rs <= mls-mrs)   //如果当前差或相等更小,则更新。//遍历[1,r],肯定能找出最优的x=i;
			{
				mls=ls;
				mrs=rs;
				ans=i;
			}
		}
		printf("%lld\n",ans);
	}
	return 0;
}</span>

你可能感兴趣的:(ACM-ICPC北京赛区2015 A hihoCoder 1249 Xiongnu's Land)