zoukankan      html  css  js  c++  java
  • CCF NOI1101(子矩阵求和)

    题目描述

    给出一个n行m列的矩阵,矩阵的每个位置有一个非负整数a[i][j],有q次询问,每次询问求一个左上角为(a,b),右下角为(c,d)的子矩阵的所有数之和。

    输入

    第一行两个整数n,m,表示矩阵的行和列的大小
    接下来n行每行m个整数,为矩阵内容
    接下来一行为一个整数q,表示询问次数
    接下来q行每行4个整数a,b,c,d,含义见题面。

    输出

    共q行,第i行为第i个询问的答案。

    样例输入

    3 5
    1 2 3 4 5
    3 2 1 4 7
    2 4 2 1 2
    3
    1 1 3 5
    2 2 3 3
    1 1 3 3

    样例输出

    43
    9
    20

    数据范围限制

    n*m<=100,000,a[i][j]<=1000,q<=100,000,1<=a<=c<=n,1<=b<=d<=m

    分析: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
    ",ans);
        }
        return 0;
    }
    View Code

    还有一种更快的方法,把以上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
    ",sum[x2*M+y2]-sum[x2*M+y1-1]-sum[M*(x1-1)+y2]+sum[M*(x1-1)+y1-1]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    【习题 6-10 UVA
    【习题 6-9 UVA
    【习题 6-8 UVA
    【NOIP2016练习】T1 挖金矿(二分答案)
    O(n)求1-n的逆元
    【NOIP2016练习】T1 string (计数)
    【NOIP2016练习】T2 跑跑步 (数论)
    【NOIP2016练习】T3 tree (树形DP)
    【CF679B】Theseus and labyrinth(数学,贪心)
    【NOIP2016练习】T2 旅行(树形DP,换根)
  • 原文地址:https://www.cnblogs.com/ACRykl/p/8342537.html
Copyright © 2011-2022 走看看