HDU 6122

来源:互联网 发布:数据库概论第5版答案 编辑:程序博客网 时间:2024/04/30 07:00

题意:有一个nn行mm列的棋盘,最初每个位置是指定的红色或蓝色或白色。你要将白色的位置染成红色或蓝色,使得对于任意一个长宽均为偶数的连续子棋盘,其中红色和蓝色的位置数相等,求方案数模998244353。1n,m103,1n,m103​​ 。

即每个2*2连续子矩阵红蓝数量相等。令红为1,蓝为0,如果让把所有格子按行号与列号的和奇偶反色,则转化为每个2*2子矩阵对角线的和相等。发现这个条件当且仅当每行都是全1或全0,或者每列都是全1或全0,讨论一下就好了。

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define N 1010typedef long long ll;const ll mod=998244353;char g[N][N];int n,m;ll calc(int k){    if(k==-1) return 0;    ll ans=1;    while(k)    {        ans=ans*2%mod;        --k;    }    return ans;}int main(){    int ca;    scanf("%d",&ca);    while(ca--)    {        scanf("%d%d",&n,&m);        int row=n,col=m,num[2]={0};        for(int i=0;i<n;++i)        {            scanf("%s",g[i]);            //printf("%s\n",g[i]);            int c,flag=-1;            for(int j=0;j<m;++j)            {                if(row==-1) break;                if(g[i][j]=='?') continue;                if(g[i][j]=='R') c=0;                else c=1;                if((i+j)&1) c^=1;                ++num[c];                if(flag==-1) flag=c;                else if(flag!=c) row=-1;            }            if(row!=-1&&flag!=-1) --row;        }        for(int j=0;j<m;++j)        {            int c,flag=-1;            for(int i=0;i<n;++i)            {                if(col==-1) break;                if(g[i][j]=='?') continue;                if(g[i][j]=='R') c=0;                else c=1;                if((i+j)&1) c^=1;                if(flag==-1) flag=c;                else if(flag!=c) col=-1;            }            if(col!=-1&&flag!=-1) --col;        }        //printf("%d %d ?\n",row,col);        ll ans=(calc(row)+calc(col))%mod;        if(num[0]==0) ans=(ans-1+mod)%mod;        if(num[1]==0) ans=(ans-1+mod)%mod;        printf("%lld\n",ans);    }    return 0;}
原创粉丝点击