码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 2461 Rectangles#容斥原理

时间:2016-03-18 21:44:07      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:

http://acm.hdu.edu.cn/showproblem.php?pid=2461

题目很简单,但是由于询问数M可以很大,所以容易超时,这道题学到了在结构体里面写函数的方法,这样子效率更高,否则的话,这道题就TLE了。

 

根据容斥原理,先把每个小长方形的面积加上,然后看有没有与该小长方形相交的,用dfs实现,当相交面积为0时,则不进行dfs,且同样遵循奇加偶减(但代码里因为是以第二个作为depth=1开始进行dfs的,所以是奇减偶加)。

 

AC代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;

struct Node
{
    int x1,x2,y1,y2;
    Node cross(Node &R)
    {
        Node tmp;
        tmp.x1=max(x1,R.x1);
        tmp.y1=max(y1,R.y1);
        tmp.x2=min(x2,R.x2);
        tmp.y2=min(y2,R.y2);
        return tmp;
    }
    int area()
    {
        if(x1>=x2||y1>=y2) return 0;
        return (x2-x1)*(y2-y1);
    }
}node[25];

int num,r[25],ans;
void dfs(int depth,Node R,int index)
{
    Node tmp;
    for(int i=index;i<=num;i++)
    {
        tmp=R.cross(node[r[i]]);
        if(tmp.area())
        {
            if(depth&1)
                ans-=tmp.area();
            else ans+=tmp.area();
            dfs(depth+1,tmp,i+1);
        }
    }
}

int main()
{
    int n,m,cas=0;
    while(scanf("%d%d",&n,&m)&&n+m)
    {
        cas++;
        for(int i=1;i<=n;i++)
            scanf("%d%d%d%d",&node[i].x1,&node[i].y1,&node[i].x2,&node[i].y2);
        printf("Case %d:\n",cas);

        for(int i=1;i<=m;i++)
        {
            ans=0;
            scanf("%d",&num);
            for(int j=1;j<=num;j++)
                scanf("%d",&r[j]);
            for(int j=1;j<=num;j++)
            {
                ans+=node[r[j]].area();
                dfs(1,node[r[j]],j+1);
            }
            printf("Query %d: %d\n",i,ans);
        }
        printf("\n");
    }
    return 0;
}

HDU 2461 Rectangles#容斥原理

标签:

原文地址:http://www.cnblogs.com/atmacmer/p/5293586.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!