zoukankan      html  css  js  c++  java
  • BZOJ5133: [CodePlus2017年12月]白金元首与独舞

    BZOJ5133: [CodePlus2017年12月]白金元首与独舞

    https://lydsy.com/JudgeOnline/problem.php?id=4894

    分析:

    • 可以发现原来就确定的那些格子不会影响答案,除非有某个格子会使得出现环。
    • 预处理出来每个格子会走到哪里,对每个不确定的格子向四周都走一下,向他们连边。
    • 设走到外部为根,转化成有向树计数问题。

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define N 305
    #define mod 1000000007
    typedef long long ll;
    ll qp(ll x,ll y) {
    	ll re=1; for(;y;y>>=1,x=x*x%mod) if(y&1) re=re*x%mod; return re;
    }
    char g[N][N];
    int n,vis[N][N],col[N][N],m;
    int FLG=0,idx[N][N],to[N][N],tot;
    ll a[N][N];
    int dfs(int x,int y) {
    	if(vis[x][y]) {FLG=1; return -1;}
    	if(g[x][y]=='.') return idx[x][y];
    	if(x<1||x>n||y<1||y>m) return tot;
    	if(to[x][y]) return to[x][y];
    	vis[x][y]=1;
    	if(g[x][y]=='L') to[x][y]=dfs(x,y-1);
    	else if(g[x][y]=='R') to[x][y]=dfs(x,y+1);
    	else if(g[x][y]=='U') to[x][y]=dfs(x-1,y);
    	else to[x][y]=dfs(x+1,y);
    	vis[x][y]=0;
    	return to[x][y];
    }
    int tx[]={0,1,0,-1};
    int ty[]={1,0,-1,0};
    ll Gauss(int n) {
    	int i,j,k,flg=0; ll del,ans=1;
    	for(i=1;i<=n;i++) {
    		for(j=i;j<=n&&!a[j][i];j++) ;
    		if(j>n) continue;
    		if(i!=j) {
    			for(k=i;k<=n;k++) swap(a[i][k],a[j][k]); flg^=1;
    		}
    		for(j=i+1;j<=n;j++) if(a[j][i]) {
    			del=a[j][i]*qp(a[i][i],mod-2)%mod;
    			for(k=i;k<=n;k++) a[j][k]=(a[j][k]-a[i][k]*del)%mod;
    		}
    	}
    	for(i=1;i<=n;i++) ans=ans*a[i][i]%mod;
    	if(flg) ans=-ans;
    	return (ans+mod)%mod;
    }
    int main() {
    	/*freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout)*/
    	int T;
    	scanf("%d",&T);
    	while(T--) {
    		memset(vis,0,sizeof(vis));
    		memset(a,0,sizeof(a));
    		memset(to,0,sizeof(to));
    		memset(idx,0,sizeof(idx));
    		scanf("%d%d",&n,&m);
    		int i,j;
    		for(i=1;i<=n;i++) scanf("%s",g[i]+1);
    		FLG=0;
    		tot=0;
    		for(i=1;i<=n;i++) for(j=1;j<=m;j++) if(g[i][j]=='.') idx[i][j]=++tot;
    		tot++;
    		for(i=1;i<=n;i++) {
    			for(j=1;j<=m;j++) if(g[i][j]!='.') {
    				dfs(i,j);		
    			}
    		}
    		if(FLG) {puts("0"); continue;}
    		for(i=1;i<=n;i++) {
    			for(j=1;j<=m;j++) if(g[i][j]=='.') {
    				int x=i,y=j;
    				int k;
    				for(k=0;k<4;k++) {
    					int dx=x+tx[k], dy=y+ty[k];
    					if(g[dx][dy]=='.') to[x][y]=idx[dx][dy];
    					else if(dx<1||dx>n||dy<1||dy>m) to[x][y]=tot;
    					else to[x][y]=to[dx][dy];
    					a[idx[x][y]][idx[x][y]]++;
    					a[ to[x][y]][idx[x][y]]--;
    				}
    			}
    		}
    		/*for(i=1;i<tot;i++) {
    			for(j=1;j<tot;j++) printf("%lld ",a[i][j]);
    			puts("");
    		}*/
    		printf("%lld
    ",Gauss(tot-1));
    	}
    }
    
  • 相关阅读:
    继承
    成员变量,局部变量,静态变量
    几种常用排序
    jdk环境配置以及java执行过程
    基础语法
    数据类型
    关键字和标识符
    网络编程(二)-socket套接字
    反射
    多态
  • 原文地址:https://www.cnblogs.com/suika/p/10229732.html
Copyright © 2011-2022 走看看