NC20017. [HEOI2015]小Z的房间
描述
输入描述
第一行两个数分别表示n和m。
接下来n行,每行m个字符,每个字符都会是’.’或者’*’,其中’.’代表房间,’*’代表柱子。
输出描述
一行一个整数,表示合法的方案数 Mod 10^9
示例1
输入:
3 3 ... ... .*.
输出:
15
C++(clang++11) 解法, 执行用时: 9ms, 内存消耗: 500K, 提交时间: 2021-04-14 13:49:43
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> pii; typedef long long ll; const int N=105; const int mod=1e9; ll f[N][N],tot,s[N][N]; int dx[4] = {0, 0, 1, -1}, dy[4] = {1, -1, 0, 0} ; int main(){ auto add=[&](int u,int v){ if(u>v)return; f[u][u]++;f[v][v]++;f[u][v]--;f[v][u]--; }; auto guass=[&](){ ll ans=1; for(int i=1;i<tot;i++){ for(int j=i+1;j<tot;j++){ while(f[j][i]){ ll t=f[i][i]/f[j][i]; for(int k=i;k<tot;k++) f[i][k]=(f[i][k]-t*f[j][k]+mod)%mod; swap(f[i],f[j]); ans=-ans; } } ans=ans*f[i][i]%mod; } if(ans<0)ans+=mod; return ans; }; int n,m;scanf("%d %d",&n,&m); for(int i=1;i<=n;i++){ char tmp[15];scanf(" %s",tmp+1); for(int j=1;j<=m;j++)if(tmp[j]=='.')s[i][j]=++tot; } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ for(int d=0;d<4;d++){ int x = i + dx[d], y = j + dy[d] ; if (s[i][j] && s[x][y]) add (s[i][j], s[x][y]) ; } } } printf("%lld\n",guass()); }