POJ--3695(容斥原理)

2015-05-16 01:29:10

题目:最多15个矩形,每次挑选一定数量的矩形进行覆盖,问总面积。

思路:容斥水题,1个矩形的面积 - 2个矩形面积的交 + 3个矩形面积的交 .... ,处理一下矩形两个点的坐标的变换即可。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;

#define getmid(l,r) ((l) + ((r) - (l)) / 2)
#define MP(a,b) make_pair(a,b)
#define PB(a) push_back(a)

typedef long long ll;
typedef pair<int,int> pii;
const double eps = 1e-8;
const int INF = (1 << 30) - 1;

int N,M,l[30],R;
ll ans;
struct Rec{
    int a1,b1,a2,b2;
}r[30];

void Dfs(int p,int cnt,int a1,int b1,int a2,int b2){
    if(a1 > a2 || b1 > b2) return;
    if(p > R){
        if(cnt == 0) return;
        int area = (a2 - a1) * (b2 - b1);
        //printf("cnt : %d , %d %d %d %d\n",cnt,a1,b1,a2,b2);
        if(cnt & 1) ans += area;
        else ans -= area;
        return;
    }
    int id = l[p];
    Dfs(p + 1,cnt,a1,b1,a2,b2);
    Dfs(p + 1,cnt + 1,max(a1,r[id].a1),max(b1,r[id].b1),
            min(a2,r[id].a2),min(b2,r[id].b2));
}


int main(){
    int tt = 0;
    while(scanf("%d%d",&N,&M) != EOF,N + M){
        for(int i = 1; i <= N; ++i)
            scanf("%d%d%d%d",&r[i].a1,&r[i].b1,&r[i].a2,&r[i].b2);
        printf("Case %d:\n",++tt);
        for(int i = 1; i <= M; ++i){
            scanf("%d",&R);
            for(int j = 1; j <= R; ++j) scanf("%d",&l[j]);
            ans = 0;
            Dfs(1,0,0,0,1000,1000);
            printf("Query %d: %lld\n",i,ans);
        }
        puts("");
    }
    return 0;
}

 

posted @ 2015-05-16 01:31  Naturain  阅读(136)  评论(0编辑  收藏  举报