id==3时错了,显示wrong answer Too long on line 2.
#include<bits/stdc++.h>
#define m0(a) memset(a,0,sizeof(a))
#define endl '\n'
#define int long long
#define f(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
const int mod = 998244353, N = 1e3+5;
int n, m, c, f;
int T, id;
int cnt[N][N];//lst-j
char a[N][N];//表示第 i 行第 j 列这个位置有土坑
bool ck(int x,int y){return a[x][y]=='0';}
void Init() {
m0(cnt);
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> T >> id;
while (T--) {//注意边界情况
cin >> n >> m >> c >> f; //n,m 分别表示花园的行数、列数 c,f=0/1
Init();
f(i, 1, n)
f(j, 1, m)
cin >> a[i][j];//debug:输入0,1字符串黏在一起了 不能直接用int二维数组
if (id == 1) {
cout << 0 << ' ' << 0 << endl;
continue;
}
if (id == 2) {
//if (!(a[1][1]) && !a[1][2] && !a[2][1] && !a[3][1] && !a[3][2])
if(ck(1,1) && ck(1,2) && ck(2,1) && ck(3,1) && ck(3,2))cout << 1 << ' ' << 0 << endl;
else cout << 0 << ' ' << 0 << endl;
continue;
}
if (id == 3) {
int numc = 0, numf = 0;
//if (!(a[1][1]) && !a[1][2] && !a[2][1] && !a[3][1] && !a[3][2])
if( ck(1,1) && ck(1,2) && ck(2,1) && ck(3,1) && ck(3,2))
{
++numc;
if (ck(4,1)) ++numf;
}
//if (!( a[2][1] || a[2][2] || a[3][1] || a[4][1] || a[4][2]))
if(ck(2,1) && ck(2,2) && ck(3,1) && ck(4,1) && ck(4,2))++numc;
if(ck(1,1) && ck(1,2)&& ck(2,1) && ck(3,1)&& ck(4,1) && ck(4,2)) ++numc;
cout<<c*numc<<' '<<f*numf;
continue;
}
//if(id==5) {cout<<0<<' '<<0<<endl;continue;}//A
// f(i, 1, n)
// f(j, 1, m)
// cout<<i<<' '<<j<<' '<<a[i][j]<<endl;
f(i,1,n)
{
int lst=0;
for(int j=m;j>=1;j--)
{
if(ck(i,j))
{
if(!lst) lst=j;
else cnt[i][j]=lst-j;
}
else lst=0;
// cout<<"lst:"<<lst<<endl;
// cout<<i<<' '<<j<<' '<<cnt[i][j]<<endl;
}
}
int vc=0,vf=0;
f(j,1,m)
{
int sum=0,ans=0,tans=0;//sum:上面多少种横 ans:该列点为节点的C个数 tans用于算V_f
f(i,1,n)
{
if(ck(i,j)&&sum) //sum>0保证没断
vf+=tans;
if(cnt[i][j])
{
//if(sum)/*(i,j)为C的左下节点*/
ans+=cnt[i][j]*(sum-cnt[i-1][j]);
tans+=cnt[i][j]*(sum-cnt[i-1][j]);
sum+=cnt[i][j];
}
else if(!ck(i,j)) sum=0,tans=0;//断了 前面的一横就用不上了
}
vc+=ans;
}
cout<<vc *c %mod<<' '<<vf *f %mod<<endl;
}
return 0;
}