1. 程式人生 > >Matrix from Arrays(陣列中的矩陣)

Matrix from Arrays(陣列中的矩陣)

題目連結

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;
}