Matrix from Arrays(阵列中的矩阵)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_41181771/article/details/81489250

题目链接

Problem Description

Kazari has an array A length of L, she plans to generate an infinite matrix M using A.
The procedure is given below in C/C++:

int cursor = 0;
for (int i = 0; ; ++i) {
for (int j = 0; j <= i; ++j) {
M[j][i - j] = A[cursor];
cursor = (cursor + 1) % L;
}
}

Her friends don’t believe that she has the ability to generate such a huge matrix, so they come up with a lot of queries about M, each of which focus the sum over some sub matrix. Kazari hates to spend time on these boring queries. She asks you, an excellent coder, to help her solve these queries.

Input

The first line of the input contains an integer T (1≤T≤100) denoting the number of test cases.
Each test case starts with an integer L (1≤L≤10) denoting the length of A.
The second line contains L integers A0,A1,…,AL−1 (1≤Ai≤100).
The third line contains an integer Q (1≤Q≤100) denoting the number of queries.
Each of next Q lines consists of four integers x0,y0,x1,y1 (0≤x0≤x1≤108,0≤y0≤y1≤108) querying the sum over the sub matrix whose upper-leftmost cell is (x0,y0) and lower-rightest cell is (x1,y1).

Output

For each test case, print an integer representing the sum over the specific sub matrix for each query.

Sample Input

1
3
1 10 100
5
3 3 3 3
2 3 3 3
2 3 5 8
5 1 10 10
9 99 999 1000

Sample Output

1
101
1068
2238
33076541

题意解析:
给出的代码是用来建立一个无穷大的阵列,用来建表,输入一个矩阵的左上角和右下角坐标,求矩阵里面的元素的和,然后输出即可。emmmm当时没做出来,然后看了很多博客,也没看懂哈哈,然后自己打了表,才搞懂.
看着单数打表的结果,以为是L*L的小矩阵是循环,打出来才知道是2L*2L的小矩阵循环….
这里写图片描述
这里写图片描述
题上给的打表代码是

int cursor = 0; 
for (int i = 0; i<=4*L ; ++i) { //这里的上限,要写4L以上。不然的话,打表是打不全的...
    for (int j = 0; j <= i; ++j) { 
        M[j][i - j] = A[cursor]; 
        cursor = (cursor + 1) % L; 
    } 
}

这里写图片描述
整个大的矩形面积是S1,两个红色是S2和S3,绿色的是S4,要求黑色部分面积的话
S=S1-S2-S3+S4
然后…看代码吧:

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;
LL A[1000],M[1000][1000],L;
LL prefix_sum(int x,int y)
{
    LL i,j,N=2*L,s1=0,s2=0,s3=0,s4=0;
    for(i=0; i<N; i++)       //2L*2L的小矩阵的和
        for(int j=0; j<N; j++)
            s1+=M[i][j];
    for(i=0; i<N; i++)       //边缘的矩阵和
        for(j=0; j<y%N; j++)
            s2+=M[i][j];
    s2*=x/N;
    for(i=0; i<x%N; i++)
        for(j=0; j<N; j++)
            s3+=M[i][j];
    s3*=y/N;
    for(i=0; i<x%N; i++)       //角落的矩阵和
        for(j=0; j<y%N; j++)
            s4+=M[i][j];
    return s1*(x/N)*(y/N)+s2+s3+s4;
}
int main()
{
    int t,n,i,j;
    cin >> t;
    while(t--)
    {
        int cursor=0,x0,x1,y0,y1;
        cin >> L;
        for(i=0; i<L; i++)
            cin >> A[i];
        for(i=0; i<=4*L; ++i)
        {
            for(j=0; j<=i; ++j)
            {
                M[j][i-j]=A[cursor];
                cursor=(cursor+1)%L;
            }
        }
//        for(i=0; i<=4*L; ++i)         //输出打表的结果
//        {
//            for(j=0; j<=4*L; ++j)
//            {
//                printf("%lld ",M[i][j]);
//            }
//            printf("\n");
//        }
        cin >> n;
        while(n--)
        {
            scanf("%d %d %d %d",&x0,&y0,&x1,&y1);
            cout << prefix_sum(x1+1,y1+1)-prefix_sum(x0,y1+1)-prefix_sum(x1+1,y0)+prefix_sum(x0,y0) << endl;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41181771/article/details/81489250