HDU 2461 Rectangles#容斥原理

Posted ATM

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 2461 Rectangles#容斥原理相关的知识,希望对你有一定的参考价值。

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#容斥原理的主要内容,如果未能解决你的问题,请参考以下文章

- Visible Trees HDU - 2841 容斥原理

容斥原理——hdu2841

hdu 2841 Visible Trees 容斥原理

hdu4135Co-prime 容斥原理水题

HDU 5514 容斥原理

HDU 1796 容斥原理