在容斥原理题单里看到这个题,第一想法肯定是扫描线啊。但一看题单分析,还真是容斥。矩形相交的图形和文氏图差不多。然后dfs容斥就好了
题单里第四题:http://blog.csdn.net/shengtao96/article/details/52490020
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
struct Rec
{
int x1,y1,x2,y2;
};
Rec rec[30];
int nums[30];
int calc(Rec& t)
{
return (t.x2-t.x1)*(t.y2-t.y1);
}
bool Union(Rec& a, Rec b)
{
Rec t;
//左边界
t.x1 = max(a.x1,b.x1);
//下边界
t.y1 = max(a.y1,b.y1);
//右边界
t.x2 = min(a.x2,b.x2);
//上边界
t.y2 = min(a.y2,b.y2);
if(t.x1 < t.x2 && t.y1 < t.y2)
{
a = t;
return false;
}
return true;
}
int dfs(int n, Rec t, int num)
{
if(n == -1)
{
if(num)
{
if(num&1) return calc(t);
else return -1*calc(t);
}
return 0;
}
int ans = dfs(n-1,t,num);
//俩矩阵没交集就返回,有交集就继续
if(Union(t,rec[nums[n]-1])) return ans;
ans += dfs(n-1,t,num+1);
return ans;
}
int main()
{
int n,m;
int time = 0;
while(scanf("%d %d",&n,&m) && n+m)
{
for(int i = 0; i < n; ++i)
scanf("%d %d %d %d",&rec[i].x1,&rec[i].y1,&rec[i].x2,&rec[i].y2);
int r,res;
printf("Case %d:\n",++time);
for(int i = 1; i <= m; ++i)
{
scanf("%d",&r);
for(int i = 0; i < r; ++i)
scanf("%d",&nums[i]);
Rec t;
t.x1 = t.y1 = -1;
t.x2 = t.y2 = 1001;
res = dfs(r-1,t,0);
printf("Query %d: %d\n",i,res);
}
printf("\n");
}
return 0;
}