题意:在一个大矩形区域内有n块土地,现在汉武帝要将整个矩形区域赐给卫青和霍去病,西边给卫青,东边给霍去病,要求满足两个要求:1,赐给卫青的区域内小矩形的面积要大于等于赐给霍去病的,并且二者的差值要尽量小;2,在满足条件1的前提下赐给卫青尽量多的土地。求应在何处画分割线。
分析:其实思路很简单,场上听到有人说用线段树,树状数组,我一脸懵逼(因为不知道那些怎么写),于是就想和队友用我们的笨办法写,那就是将整个大矩形区域以1为单位分成r份,用s[i]记录每一单元上小矩形的面积,找到第一个满足条件的位置后,从该位置的下一位起继续向后看后面的是否满足条件,输出最后一个满足条件的位置即可。
反思:巨坑巨坑的uva啊,这已经是我在long long的输入输出上第二次被坑了,因为输入习惯性用了%I64d,结果。。整场比赛这道题一直wa,和队友实在感觉是不会了,结果队友赛后改成%lld交了一次,结果过了。我们算是记住教训了。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
const int maxn=1000000+5;
ll s[maxn];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(s, 0, sizeof(s));
int r,num;
scanf("%d%d",&r,&num);
int x,y;
ll w, h;
ll sum = 0;
for(int k = 0; k < num; k++)
{
scanf("%d%d%lld%lld",&x,&y,&w,&h);//注意w h用long long
sum += w * h;//记录总面积
for(int i = x; i <= x + w - 1 && i <= r - 1; i++)
s[i] += h;//记录加入这个矩形后某些区域即区间[x,x + w - 1]内增加后的面积
}
ll tmp = 0;
int l,k;
for(l = 0; l <= r - 1; l++)
{
tmp += s[l];
if(tmp * 2 >= sum) break;//从左到右扫,找到第一个使前面的面积和大于等于总面积和一般的位置
}
ll tmp2 = tmp;
for(k = l + 1; k <= r - 1; k++)//从找到的位置的下一位继续向右扫,直到扫到最后一个满足条件的位置,将其输出即可
{
tmp2 += s[k];
if(tmp2 != tmp) break;
}
printf("%d\n",k);
}
return 0;
}