丹青千秋酿,一醉解愁肠。 无悔少年枉,只愿壮志狂。
入阵曲
题解在代码里。ios
#include<iostream> #include<cstdio> #include<cstring> using namespace std; long long a[1000][1000],sum[1000][1000],ans=0,tot,n,m,k,flag[1100000],b[1110000]; int main() { cin>>n>>m>>k; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { scanf("%lld",&a[i][j]); sum[i][j]=sum[i][j-1]+a[i][j]+sum[i-1][j]-sum[i-1][j-1];//sum数组存矩阵的和; } for(int i=0;i<n;i++)//枚举行 for(int j=i+1;j<=n;j++)//枚举行 { //memset(flag,0,sizeof(flag));//不能用memset,速度太慢,会超时13个点 flag[0]=1;//由于mod k等于0说明它本身就能组成一个矩阵mod k等于0;因此一开始赋值为1 for(int t=1;t<=m;t++)//枚举列 { b[t]=(sum[i][t]-sum[j][t])%k; if(b[t]<0) b[t]+=k;//可能小于0,因此要加k变为正数 ans+=flag[b[t]];//关键地方,前面算出有多少mod k余吧b[t],当前 b[t]-以前mod k余b[t]的能够获得一个mod k余0的矩阵; flag[b[t]]++;//由于此时多了一个上面得出来的; } for(int t=1;t<=m;t++) flag[b[t]]=0;//清空flag数组 } printf("%lld",ans); return 0; }