NOIP基础算法与经典问题02 二维前缀和
2017-11-03 13:38
323 查看
相信来看二维前缀和维护的各位一定是对一维前缀和维护问题有足够的了解了,那么二维的前缀和维护实际上是在一维前缀和维护的基础上的升级,把一个数列升级成了矩阵,但是思想是一样的,具体问题如下:
问题描述:
已知n*n的矩阵a,有m次询问,每次询问给定x1,y1,x2,y2四个数,求以(x1,y1)为左上角坐标和(x2,y2)为右下角坐标的子矩阵的所有元素和。注意仍然包含左上角和右下角的元素。
输入数据:
第一行n和m,接下来一行有n行,每行n个数,表示矩阵a,接下来有m行,每行有四个数x1,y1,x2,y2,详细解释参考问题描述。
输出数据:
m行,每行一个求和解。
输入样例:
5 2
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
2 2 4 4
3 3 5 5
输出样例:
117
171
数据范围:
0
问题描述:
已知n*n的矩阵a,有m次询问,每次询问给定x1,y1,x2,y2四个数,求以(x1,y1)为左上角坐标和(x2,y2)为右下角坐标的子矩阵的所有元素和。注意仍然包含左上角和右下角的元素。
输入数据:
第一行n和m,接下来一行有n行,每行n个数,表示矩阵a,接下来有m行,每行有四个数x1,y1,x2,y2,详细解释参考问题描述。
输出数据:
m行,每行一个求和解。
输入样例:
5 2
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
2 2 4 4
3 3 5 5
输出样例:
117
171
数据范围:
0
#include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <ctime> #include <cmath> #include <algorithm> using namespace std; const int MAXN=1010; int n,m,a[MAXN][MAXN]; //读入优化 int read(){ char ch=getchar(); bool fl=0; int r=0; if(ch=='-'){ fl=1; ch=getchar(); } while(ch>='0'&&ch<='9'){ r*=10; r+=ch-'0'; ch=getchar(); } return fl?-r:r; } //输出优化 void write(int x){ if(x<0){ putchar('-'); x=-x; } if(x>9){ write(x/10); } putchar(x%10+'0'); } int main(){ freopen("in.txt","r",stdin); freopen("std.txt","w",stdout); n=read(); m=read(); //前n项子矩阵和求法,O(n*n)复杂度 a[0][0]=read(); for(int i=1;i<n;++i){ a[0][i]=read(); a[0][i]+=a[0][i-1]; } for(int i=1;i<n;++i){ a[i][0]=read(); a[i][0]+=a[i-1][0]; for(int j=1;j<n;++j){ a[i][j]=read(); a[i][j]=a[i][j]+a[i-1][j]+a[i][j-1]-a[i-1][j-1]; } } for(int i=0;i<m;++i){ int x,y,x1,y1; x=read(); y=read(); x1=read(); y1=read(); if(x==1 && y==1){ write(a[x1-1][y1-1]); }else if(x==1){ write(a[x1-1][y1-1]-a[x1-1][y-2]); }else if(y==1){ write(a[x1-1][y1-1]-a[x-2][y1-1]); }else{ write(a[x1-1][y1-1]-a[x-2][y1-1]-a[x1-1][y-2]+a[x-2][y-2]);//输出结果,单次O(1),总共O(m) } //这里我一开始犯了个致命的错误,当我和我的暴力程序打对拍的时候才发现 //当x或者y为1的时候,我们可能不需要减去某些不存在的矩阵 //如果你是按照1为数组第一个数的下标的时候是完全不需要考虑这个问题的 //因为0下标的一定是0 //但对于我的程序,我作为一名专业的程序员 不是很喜欢1开始,所以这里我发现了致命的越界问题 //这也是导致我在对拍的时候爆0的原因 //所以我才会用连环的if-else-if来解决这个问题 putchar('\n'); } return 0; }
相关文章推荐
- NOIP基础算法与经典问题01 一维前缀和
- noip数据结构与算法 之 基础小算法 2 二维前缀和维护
- NOIP--组合数问题(数位DP+二维前缀和数组优化)
- 算法基础经典问题
- 【算法导论学习-29】动态规划经典问题02:最长公共子序列问题(Longest common subsequence,LCS)
- noip数据结构与算法 之 基础小算法 1 一维前缀和维护
- 基础算法学习(02)-Union-Find问题
- 【算法导论学习-29】动态规划经典问题02:最长公共子序列问题(Longest common subsequence,LCS)
- 程序员必知的10大经典基础实用算法
- JAVA代码—算法基础:反转整数问题
- 【算法基础】递归分治算法解决汉诺塔问题
- 【算法设计与分析基础】8、穷举 旅行商问题
- 计算几何 二维凸包问题 Andrew算法
- 经典算法之活动选择问题
- 经典问题的算法与实现
- Java 常用排序算法/Java经典问题算法
- 经典算法之背包问题
- 几个比较经典的算法问题的java实现
- linux经典问题——基础篇
- 【经典算法问题】素数环问题