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