UVALive 7261(二分)

来源:互联网 发布:英雄联盟 mac 编辑:程序博客网 时间:2024/06/08 18:48

题目链接: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<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;}


0 0
原创粉丝点击