ppip @ 2023-02-25 22:02:05
rt。思路:枚举多少列分割线,此时行分割线的个数确定,简单计数就好了。
#include <bits/stdc++.h>
using namespace std;
template <typename T>
void read(T& x) {
char c;int f{1};
do x=(c=getchar())^48;
while (!isdigit(c)&&c!='-');
if (x==29) f=-1,x=0;
while (isdigit(c=getchar()))
x=(x<<3)+(x<<1)+(c^48);
x*=f;
}
template <typename T,typename ...Args>
void read(T& x,Args&... args) {read(x);read(args...);}
constexpr int b6e0{998244353};
char mp[2005][2005];
int cc[2005],cr[2005];
int main() {
int n,m;read(n,m);
int ct{0};
for (int i{1};i<=n;++i) {
scanf("%s",mp[i]+1);
for (int j{1};j<=m;++j)
if (mp[i][j]=='Y')
++cc[j],++cr[i],++ct;
}
if (ct&1) {
puts("0");
return 0;
}
ct>>=1;
int ans{0};
for (int c{1};c<=ct&&c<=m;++c)
if (ct%c==0) {
int r{ct/c};
int fp{1},cnt,sas{1};
int CT{ct<<1};
for (int i{1};i<=c;++i) {
cnt=0;
while (fp<=m&&cnt<CT/c) cnt+=cc[fp++];
if (cnt!=CT/c) goto bed;
cnt=1;
while (fp<=m&&!cc[fp]) ++cnt,++fp;
sas=1LL*sas*cnt%b6e0;
}
fp=1;
for (int i{1};i<=r;++i) {
cnt=0;
while (fp<=n&&cnt<CT/r) cnt+=cr[fp++];
if (cnt!=CT/r) goto bed;
cnt=1;
while (fp<=n&&!cr[fp]) ++cnt,++fp;
sas=1LL*sas*cnt%b6e0;
}
(ans+=sas)%=b6e0;
bed:;
}
cout<<ans<<endl;
return 0;
}
by dehsirehC @ 2023-02-25 22:05:45
如果最后十个点里面有的点错了可能是没判枚举完之后答案为 0
by ppip @ 2023-02-25 22:11:41
@liqingyang 最后10个全错
by dehsirehC @ 2023-02-25 22:16:24
@ppip 那你多半就是压根没判 0
我的做法需要找到分割线之后暴力判断每个连通块是否为
by ppip @ 2023-02-25 22:19:28
@liqingyang 是的,但是暴力判每个块复杂度为什么是对的?
by ppip @ 2023-02-25 22:20:30
我脑抽。总数的约数最多根号个。
by dehsirehC @ 2023-02-25 22:22:54
@ppip ?不是吧总数是
约数个数貌似很小并且不太能跑满所以能过?
by ppip @ 2023-02-25 22:25:04
过了。感谢。
by ppip @ 2023-02-25 22:26:06
@liqingyang 就是说小常数
by dehsirehC @ 2023-02-25 22:27:25
@ppip 事实上
by ppip @ 2023-02-25 22:28:59
@liqingyang 你说得对,暴搜了一下,
拜谢大佬。