周末训练笔记+hdu1255+4288

来源:互联网 发布:重生小说改编的网络剧 编辑:程序博客网 时间:2024/05/24 02:09

线段树专题的题目基本差不多了,但是还有很多地方不是很清楚,裸的线段树都给我卡住过,这也是没谁了,还得继续积累。

覆盖的面积

Time Limit : 10000/5000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 36   Accepted Submission(s) : 17
Problem Description
给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.


 

Input
输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1<=N<=1000),代表矩形的数量,然后是N行数据,每一行包含四个浮点数,代表平面上的一个矩形的左上角坐标和右下角坐标,矩形的上下边和X轴平行,左右边和Y轴平行.坐标的范围从0到100000. 注意:本题的输入数据较多,推荐使用scanf读入数据.
 

Output
对于每组测试数据,请计算出被这些矩形覆盖过至少两次的区域的面积.结果保留两位小数.
 

Sample Input
251 1 4 21 3 3 72 1.5 5 4.53.5 1.25 7.5 46 3 10 730 0 1 11 0 2 12 0 3 1
 

Sample Output
7.630.00
求重复覆盖大于等于两次的区域的面积
首先,这个题目的描述我不是很确定是不是出现了问题,左上角和右下角~~不应该是左下角和右上角~~样例都是
后者的~~~
这个题目看了好久,卡了半年,本来是打算矩形总面积减去减去区域总面积的,但是重复二次以上的会出现少减
的时候,也就是这样得到的答案会偏大。下面的代码思想很好,把每个竖直方向上的线段存储,x,y上下断点的
坐标,经过处理,累加求和。。这个更新和更新节点的代码值得好好研究
#include<stdio.h>#include<string.h>#include<stdio.h>#include<algorithm>#include<iostream>using namespace std;#define lson l,mid,rt<<1#define rson mid,r,rt<<1|1#define long long llconst int MAXN=2222;struct Node{    int l,r;    int c;    double lf,rf;    double cnt;    double more;}seg[MAXN<<2];struct Line{    double x,y1,y2;    double f;}line[MAXN];double y[MAXN];bool cmp(Line a,Line b){    return a.x<b.x;}void Build(int l,int r,int rt){    seg[rt].l=l;    seg[rt].r=r;    seg[rt].cnt=0;    seg[rt].more=0;    seg[rt].lf=y[l];    seg[rt].rf=y[r];    if(l+1==r)return;    int mid=(l+r)>>1;    Build(lson);    Build(rson);}void pushup(int rt){    if(seg[rt].c>=2)    {        seg[rt].more=seg[rt].cnt=seg[rt].rf-seg[rt].lf;        return;    }    else if(seg[rt].c==1)    {        seg[rt].cnt=seg[rt].rf-seg[rt].lf;        if(seg[rt].l+1==seg[rt].r)seg[rt].more=0;        else seg[rt].more=seg[rt<<1].cnt+seg[(rt<<1)|1].cnt;    }    else    {        if(seg[rt].l+1==seg[rt].r)        {            seg[rt].cnt=seg[rt].more=0;        }        else        {            seg[rt].cnt=seg[rt<<1].cnt+seg[(rt<<1)|1].cnt;            seg[rt].more=seg[rt<<1].more+seg[(rt<<1)|1].more;        }    }}void update(int rt,Line e){    if(e.y1==seg[rt].lf&&seg[rt].rf==e.y2)    {        seg[rt].c+=e.f;        pushup(rt);        return;    }    if(e.y2<=seg[rt<<1].rf) update(rt<<1,e);    else if(e.y1>=seg[(rt<<1)|1].lf) update((rt<<1)|1,e);    else    {        Line temp=e;        temp.y2=seg[rt<<1].rf;        update(rt<<1,temp);        temp=e;        temp.y1=seg[(rt<<1)|1].lf;        update((rt<<1)|1,temp);    }    pushup(rt);}int main(){    int T;    int n;    double x1,y1,x2,y2;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        int t=1;        for(int i=1;i<=n;i++)        {            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);            line[t].x=x1;            line[t].y1=y1;            line[t].y2=y2;            line[t].f=1;            y[t]=y1;            t++;            line[t].y1=y1;            line[t].y2=y2;            line[t].x=x2;            line[t].f=-1;            y[t]=y2;            t++;        }        sort(line+1,line+t,cmp);        sort(y+1,y+t);        Build(1,t-1,1);        update(1,line[1]);        double ans=0;        for(int i=2;i<t;i++)        {            ans+=seg[1].more*(line[i].x-line[i-1].x);            update(1,line[i]);        }        printf("%.2lf\n",ans);    }    return 0;}

Coder

Time Limit : 20000/10000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 12   Accepted Submission(s) : 7
Problem Description
  In mathematics and computer science, an algorithm describes a set of procedures or instructions that define a procedure. The term has become increasing popular since the advent of cheap and reliable computers. Many companies now employ a single coder to write an algorithm that will replace many other employees. An added benefit to the employer is that the coder will also become redundant once their work is done. 1
  You are now the signle coder, and have been assigned a new task writing code, since your boss would like to replace many other employees (and you when you become redundant once your task is complete).
Your code should be able to complete a task to replace these employees who do nothing all day but eating: make the digest sum.
  By saying “digest sum” we study some properties of data. For the sake of simplicity, our data is a set of integers. Your code should give response to following operations:
  1. add x – add the element x to the set;
  2. del x – remove the element x from the set;
  3. sum – find the digest sum of the set. The digest sum should be understood by

  where the set S is written as {a1, a2, ... , ak} satisfying a1 < a2 < a3 < ... < ak 
  Can you complete this task (and be then fired)?
------------------------------------------------------------------------------
1 See http://uncyclopedia.wikia.com/wiki/Algorithm
 

Input
  There’re several test cases.   In each test case, the first line contains one integer N ( 1 <= N <= 10[sup]5[/sup] ), the number of operations to process.   Then following is n lines, each one containing one of three operations: “add x” or “del x” or “sum”.   You may assume that 1 <= x <= 10[sup]9[/sup].   Please see the sample for detailed format.   For any “add x” it is guaranteed that x is not currently in the set just before this operation.   For any “del x” it is guaranteed that x must currently be in the set just before this operation.   Please process until EOF (End Of File).
 

Output
  For each operation “sum” please print one line containing exactly one integer denoting the digest sum of the current set. Print 0 if the set is empty.
 

Sample Input
9add 1add 2add 3add 4add 5sumadd 6del 3sum6add 1add 3add 5add 7add 9sum
 

Sample Output
345[hint]C++ maybe run faster than G++ in this problem.[/hint]
n次操作,add 在队伍里加上这个数,del从队列中删除这个数,sum求下标i%mod==3的坐标
线段树里总是出现这种题目,这个题目时间更是离谱,10000ms,没看错,10000ms,暴力来一发,但是超时
了,但是不甘心,借鉴别人的暴力代码,用动态数组的lower_bound和erase操作
这个题目最重要的插入就是要保持数列的有序性,我肯定是在在处理这个的时候慢了。
#include<iostream>#include<stdio.h>#include<string.h>#include<vector>#include<algorithm>using namespace std;vector<int>map;vector<int>::iterator it;int main(){    int n;    char ch[4];    while(scanf("%d",&n)!=EOF)    {        map.clear();        for(int i=0;i<n;i++)        {            long long ans=0;            scanf("%s",ch);            if(ch[0]=='a')            {                int temp;                scanf("%d",&temp);                it=lower_bound(map.begin(),map.end(),temp);                map.insert(it,temp);            }            else if(ch[0]=='d')            {                int temp;                scanf("%d",&temp);                it=lower_bound(map.begin(),map.end(),temp);                map.erase(it);            }            else            {                for(int i=2;i<map.size();i+=5)                {                    ans+=map[i];                }                cout<<ans<<endl;            }        }    }return 0;}


原创粉丝点击