1101. 子矩阵求和 (Standard IO)
时间限制: 1000 ms 空间限制: 262144 KB 具体限制
分析:map[i][j]表示左上角为(1,1),右下角为(i,j)的子矩阵的所有数之和,
map[i][j]=map[i][j-1]+map[i-1][j]-map[i-1][j-1]+x,x是矩阵中点(i,j)上的数。
#include<cstdio> #include<vector> using namespace std; vector<int> map[100100]; int main() { int N,M,Q,x; scanf("%d%d",&N,&M); for(int i=0;i<=M;i++) map[0].push_back(0);//初始化 for(int i=1;i<=N;i++) { map[i].push_back(0); for(int j=1;j<=M;j++) { scanf("%d",&x); map[i].push_back(map[i][j-1]+map[i-1][j]+x-map[i-1][j-1]); } } int x1,y1,x2,y2; scanf("%d",&Q); while(Q--) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); int ans=map[x2][y2]-map[x2][y1-1]-map[x1-1][y2]+map[x1-1][y1-1]; printf("%d\n",ans); } return 0; }
还有一种更快的方法,把以上map数组从0到N*M编号,
把二维数组变为一维(n*m<=100,000)。
#include<cstdio> int sum[200000]; int main() { int N,M,x,Q; scanf("%d%d",&N,&M); for(int i=1;i<=N;i++) { for(int j=1;j<=M;j++) { scanf("%d",&x); sum[i*M+j]=sum[(i-1)*M+j]+sum[i*M+j-1]-sum[(i-1)*M+j-1]+x; } } int x1,y1,x2,y2; scanf("%d",&Q); while(Q--) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); printf("%d\n",sum[x2*M+y2]-sum[x2*M+y1-1]-sum[M*(x1-1)+y2]+sum[M*(x1-1)+y1-1]); } return 0; }