zoukankan      html  css  js  c++  java
  • P4111 [HEOI2015]小Z的房间

    题目

    P4111 [HEOI2015]小Z的房间

    做法

    思路很容易想,但是坑点多啊!!

    首先有墙,并不能所有点都堆到矩阵然后去末行求(det),非墙点才能丢进矩阵

    动态开一下点

    有模数,不是素数,也用不了逆元,我们就要用求(det)的黑科技,辗转相除法

    具体看代码

    My complete code

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<ctime>
    using namespace std;
    typedef long long LL;
    const LL maxn=100;
    const LL p=1e9;
    const LL dx[2]={-1,0},dy[2]={0,-1};
    LL n,m,tot;
    LL D[maxn][maxn],mp[maxn][maxn],id[maxn][maxn];
    bool visit[maxn];
    inline LL Solve(){
        LL N=tot-1,tr(0),ans(1);
        for(LL i=1;i<=N;++i){
            if(visit[i])
                continue;
            for(LL j=i+1;j<=N;++j){
                if(visit[j])
                    continue;
                while(D[j][i]){
                    LL tmp=D[i][i]/D[j][i];
                    for(LL k=1;k<=N;++k){
                        D[i][k]=(D[i][k]-tmp*D[j][k]%p+p)%p;
                        swap(D[j][k],D[i][k]);
                    }
                    tr^=1;
                }
            }
            if(D[i][i]==0)
                return 0;
            ans=ans*D[i][i]%p;
        }
        if(tr)
            ans=(p-ans+p)%p;
        return ans;
    }
    int main(){
        scanf("%lld%lld",&n,&m);
        for(LL i=1;i<=n;++i){
            char s[maxn];
            scanf(" %s",s+1);
            for(LL j=1;j<=m;++j)
                if(s[j]=='.')
                    mp[i][j]=1;
        }
        for(LL i=1;i<=n;++i){
            for(LL j=1;j<=m;++j){
                if(mp[i][j]==0)
                    continue;
                id[i][j]=++tot;
                LL u(id[i][j]);
                for(LL k=0;k<2;++k){
                    LL xx(i+dx[k]),yy(j+dy[k]);
                    if(mp[xx][yy]==0)
                        continue;
                    LL v(id[xx][yy]);
                    ++D[u][u],
                    ++D[v][v],
                    D[u][v]=(D[u][v]+p-1)%p,
                    D[v][u]=(D[v][u]+p-1)%p;
                }
            }
        }
        printf("%lld
    ",Solve());
        return 0;
    }
    
  • 相关阅读:
    &与&&的区别
    x^y=(x&~y)|(~x&y)证明
    a、b交换与比较
    x+y = ((x&y)<<1) + (x^y) 证明
    (x&y) + ((x^y)>>1)即x和y的算数平均值
    默认参数提升
    类型转换
    闲扯原码,补码和反码(转)
    C/C++中float和double的存储结构
    led设备驱动(s3c_led.c)
  • 原文地址:https://www.cnblogs.com/y2823774827y/p/10265456.html
Copyright © 2011-2022 走看看