• Codeforces gym101350 2017 ACM Arabella Collegiate Programming Contest G. Snake Rana (容斥 + 二进制)


    题目链接:

    http://codeforces.com/gym/101350/problem/G

    题意:

    n*m的矩形,有k个雷,找出不包括雷的矩形有多少个?

    思路:

    K<=20,容斥原理。

    首先算出所有格子的数量,格子为rc的数量有(N−r+1)∗(M−c+1)个,枚举rc

    就是 C(n,2)*C(m,2)


    然后容斥减去有一个黑格子的,加上有两个格子的。。。。 

    至于算有g个黑格子有多少个,分别计算x,y的最大值maxx,maxy,最小值minx,miny。结果等于minx*miny*(N−maxx+1)*(M−maxy+1)

    收获: 

    容斥好神奇啊,本来是划分的东西,要减去所有包括一个雷,两个雷。。。k个雷的不合法的矩形,

    那我减去包括>=1个雷的矩形,加上>=2个雷的矩形......就很神奇的去重啦!!!

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define MS(a) memset(a,0,sizeof(a))
    #define MP make_pair
    #define PB push_back
    const int INF = 0x3f3f3f3f;
    const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
    inline ll read(){
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    //////////////////////////////////////////////////////////////////////////
    const int maxn = 1e5+10;
    
    int n,m,k;
    ll vx[25],vy[25];
    
    int main(){
        int T = read();
        while(T--){
            cin >> n >> m >> k;
            for(int i=0; i<k; i++){
                cin >> vx[i] >> vy[i];
            }
    
            ll ans = 1LL*(n+1)*n/2*(m+1)*m/2;
    
            for(int s=1; s<(1<<k); s++){
                int t = s;
                int cnt = 0;
                while(t){
                    if(t&1) cnt++;
                    t >>= 1;
                }
                ll mix=INF,miy=INF,mxx=-1,mxy=-1;
                for(int i=0; i<k; i++){
                    if((1<<i) & s){
                        mix = min(mix,vx[i]);
                        miy = min(miy,vy[i]);
                        mxx = max(mxx,vx[i]);
                        mxy = max(mxy,vy[i]);
                    }
                }
                ll res = mix*miy*(n-mxx+1)*(m-mxy+1);
                if(cnt&1) ans-=res;
                else ans+=res;
            }
            cout << ans << endl;
        }
    
    
        return 0;
    }
  • 相关阅读:
    C#扩展方法(转)
    设计模式与足球(一)创建型模式
    java设计模式之适配器模式
    java设计模式之建造者模式
    java设计模式之原型模式
    java设计模式之单例模式
    java之设计模式工厂三兄弟之抽象工厂模式
    java之设计模式工厂三兄弟之工厂方法模式
    创建对象与使用对象——谈谈工厂的作用
    java之设计模式工厂三兄弟之简单工厂模式
  • 原文地址:https://www.cnblogs.com/yxg123123/p/7230057.html
Copyright © 2020-2023  润新知