Estimating the Flood Risk(思维)

题目描述

Mr. Boat is the owner of a vast extent of land. As many typhoons have struck Japan this year, he became concerned of flood risk of his estate and he wants to know the average altitude of his land. The land is too vast to measure the altitude at many spots. As no steep slopes are in the estate, he thought that it would be enough to measure the altitudes at only a limited number of sites and then approximate the altitudes of the rest based on them.

Multiple approximations might be possible based on the same measurement results, in which case he wants to know the worst case, that is, one giving the lowest average altitude.

Mr. Boat’s estate, which has a rectangular shape, is divided into grid-aligned rectangular areas of the same size. Altitude measurements have been carried out in some of these areas, and the measurement results are now at hand. The altitudes of the remaining areas are to be approximated on the assumption that altitudes of two adjoining areas sharing an edge differ at most 1.

In the first sample given below, the land is divided into 5 × 4 areas. The altitudes of the areas at (1, 1) and (5, 4) are measured 10 and 3, respectively. In this case, the altitudes of all the areas are uniquely determined on the assumption that altitudes of adjoining areas differ at most 1.

In the second sample, there are multiple possibilities, among which one that gives the lowest average altitude should be considered.

In the third sample, no altitude assignments satisfy the assumption on altitude differences.

在这里插入图片描述
Your job is to write a program that approximates the average altitude of his estate. To be precise, the program should compute the total of approximated and measured altitudes of all the mesh-divided areas. If two or more different approximations are possible, the program should compute the total with the severest approximation, that is, one giving the lowest total of the altitudes.

输入

The input consists of a single test case of the following format.

w d n

x1 y1 z1

.

.

.

xn yn zn

Here, w, d, and n are integers between 1 and 50, inclusive. w and d are the numbers of areas in the two sides of the land.

n is the number of areas where altitudes are measured. The i-th line of the following n lines contains three integers, xi, yi, and zi satisfying 1≤xi≤w, 1≤yi≤d, and −100≤zi≤100. They mean that the altitude of the area at (xi,yi) was measured to be zi. At most one measurement result is given for the same area, i.e., for i≠j, (xi,yi)≠(xj,yj).

输出

If all the unmeasured areas can be assigned their altitudes without any conflicts with the measured altitudes assuming that two adjoining areas have the altitude difference of at most 1, output an integer that is the total of the measured or approximated altitudes of all the areas. If more than one such altitude assignment is possible, output the minimum altitude total among the possible assignments.

If no altitude assignments satisfy the altitude difference assumption, output No.

样例输入
【样例15 4 2
1 1 10
5 4 3
【样例25 4 3
2 2 0
4 3 0
5 1 2
【样例33 3 2
1 1 8
3 3 3

【样例42 2 1
1 1 -100
样例输出
【样例1130
【样例2-14
【样例3】
No
【样例4-404
思路

先来一波曼哈顿距离公式:
在这里插入图片描述
根据题目以及样例我们可以得到,任意两个标记高度的点之间的高度差应当<=它们的曼哈顿距离,即:

| h1 - h2 | <= | x1 - x2 | + | y1 - y2 |

根据这个特点,我们可以先判断这个给的数据合不合理,其次,我们还可以通过这个特点求每个没标记高度的点的高度:

h [ j ] [ k ] = max( h [ j ] [ k ] , a [ i ] . l - abs( j - a [ i ] . x ) - abs( k -a [ i ] . y ) );

//点( j , k ) 的高度可以由第 i 个被标记高度的点来更新确定,因为点 ( j , k ) 要对所有标记高度的点符合 “| h1 - h2 | <= | x1 - x2 | + | y1 - y2 |” 这个规律,所以我们每次取最大值,这样所有的差才会都满足刚才的规律

代码
#include<iostream>
#include<string>
#include<map>
#include<set>
//#include<unordered_map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<stack>
#include<cmath>
#include<fstream>
#define X first
#define Y second
#define best 131 
#define INF 0x3f3f3f3f
#define P pair<int,int>
#define ls p<<1
#define rs p<<1|1
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double eps=1e-5;
const double pai=acos(-1.0);
const int N=1e5+10;
const int maxn=1e6+10;
int w,d,n,h[60][60],ans;
bool flag;
struct node
{
    int x;
    int y;
    int l;
}a[60];
int main( )
{
    scanf("%d%d%d",&d,&w,&n);
    for(int i=1;i<=n;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].l);
    for(int i=1;i<=n;i++)
    {
        for(int j=i+1;j<=n;j++)
        {
            if(abs(a[i].l-a[j].l)>abs(a[i].x-a[j].x)+abs(a[i].y-a[j].y)) 
            {
                flag=1;
                break;
            }
        }
        if(flag) break;
    }
    if(flag) 
    {
        printf("No");
        return 0;
    }
    for(int i=1;i<=d;i++)
    {
        for(int j=1;j<=w;j++)
        {
            h[i][j]=-INF;
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=d;j++)
        {
            for(int k=1;k<=w;k++)
            {
                h[j][k]=max(h[j][k],a[i].l-abs(j-a[i].x)-abs(k-a[i].y));
            }
        } 
    }
    for(int i=1;i<=d;i++)
    {
        for(int j=1;j<=w;j++)
        {
            ans+=h[i][j];
        }
    }
    printf("%d",ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值