1. 程式人生 > 實用技巧 >CSP/NOIP新賽制內部挑戰賽3 C. maze

CSP/NOIP新賽制內部挑戰賽3 C. maze

N = 2時,棋盤上必須無障礙點,且m為奇數時有解,方案數為1.
N = 3時,觀察可以發現,中間一行所有的格子一定是必經的,且相鄰兩個格子為一個單元,同時位於第1行或者第3行。所以每個小單元方案數為2,空棋盤的方案數為2的冪次。
障礙點對於答案的影響是,限制這個單元只能選擇第1行或者第3行,因此每限制一個單元,答案除掉一個2.如果一個單元的第一行和第三行都設定了障礙,或者中間第二行有任何障礙,則無解。

N = 3時,陣列還開不下,還得用map離散一下

還有蠻多需要注意的細節


程式碼

#include<bits/stdc++.h>
using namespace std;
typedef 
long long ll; const int mod=998244353; int n,m,q; void solve2() { int x,y; for(int i=1;i<=q;i++) { scanf("%d%d",&x,&y); printf("0\n"); } } ll qpow(ll a,ll b) { ll res=1; while(b) { if(b&1) res=(res*a)%mod; b>>=1; a
=(a*a)%mod; } return res; } ll inv2; map <int,int> ban[5]; void solve3() { int x,y; inv2=qpow(2,mod-2); int flag=0; ll res=0; if(m%2==1) flag=1; if(!flag) res=qpow(2,m/2-1); for(int i=1;i<=q;i++) { scanf("%d%d",&x,&y); if(x==2|| (x==1
&& y==1) ||(x==n && y==m)) flag=1; if(flag) { printf("0\n"); continue; } if(y>1 && y<m && !ban[x][y] && !ban[x][y^1]) res=res*inv2%mod; ban[x][y]=1; if(x==1 && (ban[3][y] || ban[3][y^1])) { flag=1; printf("0\n"); continue; } if(x==3 && (ban[1][y] || ban[1][y^1])) { flag=1; printf("0\n"); continue; } printf("%lld\n",res); } } int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); scanf("%d%d%d",&n,&m,&q); if(n==2) solve2(); if(n==3) solve3(); return 0; }