Input file: standard input
Output file: standard output
Time limit: 1 second
Memory limit: 512 mebibytes
Last year, there were three soul artist in the team Abysswatcher. They were all addicted to painting, even when they were on the train. One day, they want to paint a paper. In i-th step, they choose a core grid (xi,yi) and paint all the grid near it (the Manhattan distance distance between the core and other grids are no more than ri). After some operates, they want to know the maximum times they painted the same grid.
Input
Three integers n,m,t(1≤n,m≤2000,1≤t≤2×105)in one line. n and m represent the length and the width of the paper. t represents the times they painted.
In the following t lines, the i-th contains three non-negative integers xi,yi,ri (1≤xi−ri,xi+ri≤n, 1≤yi−ri,yi+ri≤m).
Output
Two integers in one line, represent the maximum times they painted the same grid and the number of such grid.
Examples
Input 1
6 6 4
2 2 1
2 3 1
3 2 0
3 4 2
Output 1
3 2
Note
The sample looks like this. The "Manhattan distance" of two points A,B equals to ∣Ax−Bx∣+∣Ay−By∣.
\ 1 2 3 4 5 6 -> x 1 1 1 1 2 1 2 3 2 1 3 3 2 1 1 1 4 1 1 1 5 1 6 | v y 题目大意:还是比较容易懂得,在每次修改时给出一个点的坐标以及范围大小,从这个点开始出发到在范围内能到达的点就加一,求最大的值一级出现次数 思路 对于这道题,一开始值为零,而且是先修改在查询,那么我们容易想到前缀和,并且我们能发现,每次修改的时候的范围是一个菱形,通过旋转能变成一个矩形 所以我们可以通过坐标变换来使其成为一个矩形(实际上变为矩形后,矩形中所包括的点其实大于菱形的,但是没有关系,因为问题求的是最大值,没有求整个图,所以我们可以通过坐标的映射去求(实际上不是正好对应的) 至于坐标变换,我可以两条对角线;来作为xy轴,其中需要注意的是,我们求主对角线的标号是x-y+m而不是x-y+m)%m,其实很简单,对角线的数量一定大于m和n 二维前缀和参见基神的教学啦啦啦 ac代码:
#include<cstdio> #include<iostream> #include<sstream> #include<algorithm> #include<map> #include<vector> #include<cstring> using namespace std; int n,m,q; int mp[5000][5000]; int ans=-1; int main() { while(~scanf("%d%d%d",&n,&m,&q)) { ans=-1; memset(mp,0,sizeof(mp)); while(q--) { int x,y,d; scanf("%d%d%d",&x,&y,&d); int x1=x-d-y+m; int x2=x+d-y+m; int y1=y-d+x; int y2=y+d+x; mp[x1][y1]++; mp[x1][y2+1]--; mp[x2+1][y1]--; mp[x2+1][y2+1]++; } for(int i=1;i<=n+m;i++) { int tmp=0; for(int j=1;j<=n+m;j++) { tmp+=mp[i][j]; mp[i][j]=mp[i-1][j]+tmp; } } int cnt; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { int x=i-j+m; int y=i+j; if(mp[x][y]>=ans) { if(mp[x][y]==ans) cnt++; else{ ans=mp[x][y]; cnt=1; } } //cout<<mp[x][y]; } // cout<<endl; } cout<<ans<<' '<<cnt<<endl; } return 0; }