小巫女从小就喜欢吃火龙果,她有一个梦想,就是用魔法变出许许多多美味可口的火龙果,这样她就可以天天享受火龙果的美味啦!
在一个二维平面上,小巫女用火龙果画出了许多图案,她想知道这些图案中最闪耀的一点的美观度有多大。
具体的,在初始美观度均为0的平面上,小巫女画出了 n 个等腰直角三角形(其直角边平行于坐标轴),并且使得三角形内部(包含边界)的整点增加了 c 的美观度。
一幅画作完成啦,你也要回答小巫女最初提问的问题呢!
如果她高兴了,说不定会送给你她最爱吃的火龙果呢!
输入描述:
第一行,一个整数 n。
接下来 n 行,每行五个整数 opt,x,y,l,c。(请注意:坐标轴x正方向向下,y轴正方向向右)
其中,opt=1/2/3/4分别表示等腰直角三角形的直角点在左上、右上、左下、右下,其坐标为(x,y),直角边长为l,增加的美观度为c。
输出描述:
第一行,包含一个整数ans,表示二维平面中最大的美观度是多少。
示例1
输入
复制
2
1 1 1 1 1
4 3 3 2 2
输出
复制
2
说明
每个点的权值为:
1 1 2
1 2 2
2 2 2
备注:
思路
废话:一开始想了很多,什么二维前缀和,悬线法之类 的,想从里面找到灵感,后来都没用,不过忽然想到昨天线段树例题看到的一点东西,就想明白了应该怎么做
首先,假如我们从第i行,从左往右遍历过去,我们发现进入三角形后就会得到对应的美观度,从这个三角形出去之后就会失去对应的美观度,那么怎么算进入,怎么算出去。
最左边的边是入边,最右边的边是出边,我们将入边上的每一个点+C(对应的美观度),出边往右平移一格的边(即虚线)上的每一个点-C,然后每一行从左到右进行前缀和运算,mmap[i][j].c+=mmap[i][j-1].c,每一次运算得到的最大值就是答案
PS1:代码中的bool类型变量rubian和chubian没有什么用,就是自己看的,可以不加
PS2:当然你也可以把最上面的边当做入边,下面的边当做出边,然后从上到下做前缀和运算,其中的关系不要搞晕就可以,我有个朋友把y当做行,x当做列,但是题目给你的(x,y),x是行,y是列,WA的自闭2333
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#define rep(i,s,e) for(int i=s;i<=e;i++)
#define rep1(i,s,e) for(int i=s;i<e;i++)
#define rep2(i,s,e,c) for(int i=s;i>=e;i--)
#define pfi(x) printf("%d\n",x)
#define pfl(x) printf("%lld\n",x)
#define pfn() printf("\n")
#define pfs() printf(" ")
#define sfi(x) scanf("%d",&x)
#define sfi1(x,y) scanf("%d%d",&x,&y)
#define sff(x) scanf("%lf",&x)
#define sfl(x) scanf("%lld",&x)
#define memset1(x) memset(x,0,sizeof(x))
using namespace std;
typedef long long ll;
const int MAX = 1e4 + 50;
const int mod = 996873654;
struct node{
bool rubian;
bool chubian;
ll c;
}mmap[1005][1005];
int main(){
int n;
sfi(n);
memset1(mmap);
for(int i=0;i<n;i++){
int opt,x,y,l;
ll c;
scanf("%d%d%d%d%lld",&opt,&x,&y,&l,&c);
if(opt==1){//左上
for(int j=x;j<=x+l;j++){
mmap[j][y].rubian=true;
mmap[j][y].c+=c;
}
int x1=x,y1=y+l+1;
for(int k=0;k<=l;k++){
mmap[x1+k][y1-k].chubian=true;
mmap[x1+k][y1-k].c-=c;
}
}
else if(opt==2){//右上
for(int j=x;j<=x+l;j++){
mmap[j][y+1].chubian=true;
mmap[j][y+1].c-=c;
}
int x1=x,y1=y-l;
for(int k=0;k<=l;k++){
mmap[x1+k][y1+k].rubian=true;
mmap[x1+k][y1+k].c+=c;
}
}
else if(opt==3){//左下
for(int j=x;j>=x-l;j--){
mmap[j][y].rubian=true;
mmap[j][y].c+=c;
}
int x1=x-l,y1=y+1;
for(int k=0;k<=l;k++){
mmap[x1+k][y1+k].chubian=true;
mmap[x1+k][y1+k].c-=c;
}
}
else{//右下
for(int j=x;j>=x-l;j--){
mmap[j][y+1].chubian=true;
mmap[j][y+1].c-=c;
}
int x1=x,y1=y-l;
for(int k=0;k<=l;k++){
mmap[x1-k][y1+k].rubian=true;
mmap[x1-k][y1+k].c+=c;
}
}
}
ll mx=0;
for(int i=1;i<=1000;i++){
for(int j=1;j<=1000;j++){
// printf("%lld ",mmap[i][j].c);
mmap[i][j].c+=mmap[i][j-1].c;
mx=max(mx,mmap[i][j].c);
}
// pfn();
}
pfl(mx);
return 0;
}