小巫女从小就喜欢吃火龙果,她有一个梦想,就是用魔法变出许许多多美味可口的火龙果,这样她就可以天天享受火龙果的美味啦!
可是小巫女平常没有认真完成魔法学院的功课,魔法经常出现一些意想不到的情形,不能变出许多的火龙果。
于是,在一块 H × W 的田地里,她打算先变出 n 个品种的火龙果,并且种在坐标为 (xi, yi) 的格子内,并且美味程度为 ci ,然后在剩余的格子内种满任意美味程度的火龙果。但是,火龙果们要求相邻格子(指上下左右四个格子)的火龙果的美味程度 ci 的差的绝对值不超过D。
小巫女想知道整块地每个格子美味程度之和的可能值最大是多少。但她忙着施展她的魔法呢,于是她就拜托你来解决这个问题啦!
小巫女的魔法可能不稳定,如果出现了无解的情况,请输出PitayaCrying。
输入描述:
第一行,四个整数H、W、n和D。 接下来 n 行,每行三个整数x、y、c,表示在格子(x, y)的火龙果的价值为c。 (数据保证格子(x, y)在 H × W 的田地)
输出描述:
如果出现了无解的情况,请输出PitayaCrying。 否则你需要输出田地中每个格子美味程度之和对109 + 7 取模后的结果。
示例1
输入
复制
2 3 2 2 2 1 4 1 2 7
输出
复制
40
示例2
输入
复制
3 1 2 100 1 1 1 3 1 202
输出
复制
PitayaCrying
示例3
输入
复制
2 2 3 2 2 1 1 2 2 4 1 1 1
输出
复制
PitayaCrying
示例4
输入
复制
2 2 3 2 1 1 3 1 1 2 1 1 2
输出
复制
PitayaCrying
备注:
思路
为了保证美味程度(c)之和最大,应从已知的最小的c开始,找四周的格子,如果格子已知,判断两者的差值是否不超过D,如果格子未知,再判断未知格子四周的格子,找到已知的四周的格子的上界与下界的交集,然后将交集的最大值赋予该未知格子。
这里可以找出四周格子里的最大值和最小值,如果两者差值不超过2D,就是符合条件的,可以赋予未知格子的最大值就是最小值加上D。也可以跟我的代码一样取交集的最大值。
也是为了确保差值最小,每次都从最小的c开始,使用优先队列即可
PS:注意一个坑点,题目给你的n种火龙果里面,有可能(x,y)坐标是一样的,这时候你要判断他们的c的差值,做的人基本都入坑了
#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 = 1e9+7;
struct node{
int x,y;
ll c;
node():x(0),y(0),c(0){}
node(int _x,int _y,ll _c):x(_x),y(_y),c(_c){}
bool operator < ( const node & t ) const{
return c>t.c;
}
}p,p1,p2;
ll ar[2005][2005];
bool mmap[2005][2005];
int xy[][2]={{1,0},{-1,0},{0,1},{0,-1}};
int main(){
int h,w,n,d;
scanf("%d%d%d%d",&h,&w,&n,&d);
priority_queue<node> q;
memset1(mmap);
memset1(ar);
bool flag=true;
for(int i=0;i<n;i++){
scanf("%d%d%lld",&p.x,&p.y,&p.c);
if(!ar[p.x][p.y]) ar[p.x][p.y]=p.c;
else if(ar[p.x][p.y]!=p.c) flag=false;
mmap[p.x][p.y]=true;
q.push(p);
}
if(flag){
while(q.size()){
p=q.top();
q.pop();
for(int k=0;k<4;k++){
p2=p;
p2.x+=xy[k][0]; p2.y+=xy[k][1];
if(p2.x>=1&&p2.x<=h&&p2.y>=1&&p2.y<=w){
if(!mmap[p2.x][p2.y]){
ll left=0,right=0x7f7f7f7f;
for(int i=0;i<4;i++){
p1=p2;
p1.x+=xy[i][0]; p1.y+=xy[i][1];
if(p1.x>=1&&p1.x<=h&&p1.y>=1&&p1.y<=w&&mmap[p1.x][p1.y]){
ll left1=ar[p1.x][p1.y]-d,right1=ar[p1.x][p1.y]+d;
if(right1<left||right<left1){
flag=false;
break;
}
else{
if(right1>=left){
if(right1<=right) right=right1;
if(left1>=left) left=left1;
}
else if(right>=left1){
if(right>right1) right=right1;
if(left<left1) left=left1;
}
}
}
}
if(!flag) break;
mmap[p2.x][p2.y]=true;
ar[p2.x][p2.y]=right;
p2.c=right;
q.push(p2);
}
else if(abs(ar[p2.x][p2.y]-p.c)>d){
flag=false;
break;
}
}
}
if(!flag) break;
}
}
if(!flag) printf("PitayaCrying\n");
else{
ll ans=0;
for(int i=1;i<=h;i++){
for(int j=1;j<=w;j++){
ans=(ans+ar[i][j])%mod;
}
}
pfl(ans);
}
return 0;
}