UVALive 7261(二分)

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5273

题意:在一个大矩形区域内有n块土地,现在汉武帝要将整个矩形区域赐给卫青和霍去病,西边给卫青,东边给霍去病,要求满足两个要求:1,赐给卫青的区域内小矩形的面积要大于等于赐给霍去病的,并且二者的差值要尽量小;2,在满足条件1的前提下赐给卫青尽量多的土地。求应在何处画分割线。

分析:其实思路很简单,场上听到有人说用线段树,树状数组,我一脸懵逼(因为不知道那些怎么写),于是就想和队友用我们的笨办法写,那就是将整个大矩形区域以1为单位分成r份,用s[i]记录每一单元上小矩形的面积,找到第一个满足条件的位置后,从该位置的下一位起继续向后看后面的是否满足条件,输出最后一个满足条件的位置即可。

反思:巨坑巨坑的uva啊,这已经是我在long long的输入输出上第二次被坑了,因为输入习惯性用了%I64d,结果。。整场比赛这道题一直wa,和队友实在感觉是不会了,结果队友赛后改成%lld交了一次,结果过了。我们算是记住教训了。

#include
#include
#include
#include
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;
}



你可能感兴趣的:(算法,——,二分,+,三分,OJ,——,UVA)