题意。给你一个矩阵,给你两点坐标,表示一个子矩阵的左上角和右下角。
KEY:看了两小时看不懂。终于看懂了又TLE。赛后参考别人的代码,觉得我和别人的思路一样,但他的ac了,我的tle了,怪自己看不懂题意,所以代码不清晰咯。
代码:
#include <iostream>
#include <stdio.h>
#include <string.h>
int t, m, n, k, f = 1;
const int maxn = 500 + 5;
int num[maxn][maxn];
int r1, c1, r2, c2;
long long sum;
using namespace std;
int main()
{
scanf("%d", &t);
while(t--)
{
scanf("%d%d", &m, &n);
for(int i = 1; i <= m; i++)
{
for(int j = 1; j <= n; j++)
{
scanf("%d", &num[i][j]);
num[i][j] = num[i][j] * num[i][j];
}
}
scanf("%d", &k);
printf("Case %d:\n", f++);
for(int i = 1; i <= k; i++)
{
sum = 0;
scanf("%d%d%d%d", &r1, &c1, &r2, &c2);
for(int ii = r1; ii <= r2; ii++){
for(int jj = c1; jj <= c2; jj++){
sum = sum + num[ii][jj];
}
}
printf("%lld\n", sum);
}
}
return 0;
}
其实以上代码肯定会超时,之所以AC可能是数据太水了吧。接下来的这段代码复制黏贴于同学的。先把每个子矩阵的元素的平方和存在数组中,自己画画图就大概可以知道怎么构造出数值了。然后再处理次数就好了。这样复杂度就最多是100000了。
#include <stdio.h>
#include <string.h>
int matrix[510][510];
long long sum[510][510];
int main()
{
#ifdef LOCAL
freopen("data.in", "r", stdin);
#endif
int t, n, m, q, r1, c1, r2, c2;
scanf("%d", &t);
for(int i = 1; i <= t; i++)
{
printf("Case %d:\n", i);
scanf("%d%d", &n, &m);
for(int j = 1; j <= n; j ++)
for(int k = 1; k <= m; k++)
{
scanf("%d", &matrix[j][k]);
}
memset(sum, 0, sizeof(sum));
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
{
sum[i][j] = sum[i - 1][j] + sum[i][j - 1 ] +
matrix[i][j] * matrix[i][j] - sum[i - 1][j - 1];
}
scanf("%d", &q);
while(q--)
{
scanf("%d%d%d%d", &r1, &c1, &r2, &c2);
printf("%lld\n", sum[r2][c2] - sum[r2][c1 - 1]
- sum[r1 - 1][c2] + sum[r1 - 1][c1 - 1]);
}
}
return 0;
}