POJ - 3658 Artificial Lake

题意:向N个连续且高度不同的平台灌水,平台各有宽度,且高度各不相同。一开始,先向高度最低的平台灌水,直到灌满溢出,流向其他的平台,直至所有平台都被覆盖。已知每分钟注入高度为1且宽度为1的水,问每个平台恰好被高度为1的水覆盖的时间。

分析:

1、对于每个平台,L代表其左边的平台标号,R代表其右边的平台标号,随着平台被淹没,R,L会随之改变。

2、平台标号为1~n,其两侧平台0和n-1高度初始化为正无穷作为界线,因此只需统计淹没了n个平台的情况即可。

3、Find_lowest();---得到最低的平台标号。

4、update_lowest(cur);---淹没当前平台后,cur更新为水流溢出后,即将流向的平台标号。

5、将当前平台的水注满到与两侧较矮平台齐平的高度,将较矮的平台宽度更新为加上当前平台后的宽度,与此同时,更新当前平台两侧的平台的左右平台标号。

#pragma comment(linker, "/STACK:102400000, 102400000")
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#define Min(a, b) ((a < b) ? a : b)
#define Max(a, b) ((a < b) ? b : a)
const double eps = 1e-8;
inline int dcmp(double a, double b){
    if(fabs(a - b) < eps) return 0;
    return a > b ? 1 : -1;
}
typedef long long LL;
typedef unsigned long long ULL;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
const LL LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1};
const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1};
const int MOD = 1e9 + 7;
const double pi = acos(-1.0);
const int MAXN = 1e5 + 10;
const int MAXT = 10000 + 10;
using namespace std;
int N;
struct Node{
    int L, R;
    LL w, h, ans;
    void read(){
        scanf("%lld%lld", &w, &h);
    }
}num[MAXN];
int Find_lowest(){
    LL mi = LL_INF, cur = 0;
    for(int i = 1; i <= N; ++i){
        if(num[i].h < mi){
            mi = num[i].h;
            cur = i;
        }
    }
    return cur;
}
int update_lowest(int cur){
    while(1){
        int l = num[cur].L, r = num[cur].R;
        if(num[l].h < num[cur].h) cur = l;
        else if(num[r].h < num[cur].h) cur = r;
        else return cur;
    }
}
void solve(int cur){
    int cnt = 0;
    LL sum = 0;
    while(cnt < N){
        sum += num[cur].w;//将水注满到刚好覆盖该平台
        num[cur].ans = sum;
        ++cnt;
        int l = num[cur].L, r = num[cur].R;
        sum += (Min(num[l].h, num[r].h) - num[cur].h - 1) * num[cur].w;//将当前平台的水注满到与两侧较矮平台齐平的高度
        num[l].R = r;//更新两侧平台的左右平台
        num[r].L = l;
        if(num[l].h < num[r].h){
            num[l].w += num[cur].w;
            cur = l;
        }
        else{
            num[r].w += num[cur].w;
            cur = r;
        }
        cur = update_lowest(cur);
    }
}
int main(){
    scanf("%d", &N);
    for(int i = 1; i <= N; ++i){
        num[i].read();
    }
    for(int i = 0; i <= N + 1; ++i){
        num[i].L = i - 1;
        num[i].R = i + 1;
    }
    num[0].w = num[N + 1].w = 1;
    num[0].h = num[N + 1].h = LL_INF;
    int cur = Find_lowest();
    solve(cur);
    for(int i = 1; i <= N; ++i){
        printf("%lld\n", num[i].ans);
    }
    return 0;
}

  

时间: 2024-12-11 12:09:25

POJ - 3658 Artificial Lake的相关文章

【POJ 3658】Artificial Lake

Artificial Lake Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 1862   Accepted: 625 Description The oppressively hot summer days have raised the cows' clamoring to its highest level. Farmer John has finally decided to build an artificia

POJ 之2386 Lake Counting

Lake Counting Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20003   Accepted: 10063 Description Due to recent rains, water has pooled in various places in Farmer John's field, which is represented by a rectangle of N x M (1 <= N <= 10

POJ 2256 Artificial Intelligence?【字符串处理】

题目链接:http://poj.org/problem?id=2256 Artificial Intelligence? Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1323   Accepted: 643 Description Physics teachers in high school often think that problems given as text are more demanding than

【POJ - 2386】Lake Counting (dfs+染色)

-->Lake Counting 直接上中文了 Descriptions: 由于近日阴雨连天,约翰的农场中中积水汇聚成一个个不同的池塘,农场可以用 N x M (1 <= N <= 100; 1 <= M <= 100) 的正方形来表示.农场中的每个格子可以用'W'或者是'.'来分别代表积水或者土地,约翰想知道他的农场中有多少池塘.池塘的定义:一片相互连通的积水.任何一个正方形格子被认为和与它相邻的8个格子相连. 给你约翰农场的航拍图,确定有多少池塘 Input Line 1

poj 2386  Lake Counting DFS

n*m的矩阵W是水 .是地问有多少池塘池塘的定义是:W通过 八个 方向连接成的一片算作是一个池塘 样例输入中,有左上.左下.右侧三片连接在一起的W因而样例输出给出了3个池塘的答案 #include <cstdio> #include <iostream> #define N 110 using namespace std; int n,m; char s[N][N]; void dfs(int x,int y) { s[x][y]='.'; int i,j; for(i=-1; i

【POJ3658】【USACO 2008 Jan Gold】 2.Artificial Lake人工湖 单调栈

人工湖 Time Limit: 1 Sec  Memory Limit: 128 MB Description 夏日那让人喘不过气的酷热将奶牛们的烦躁情绪推到了最高点.最终,FJ 决定建一个人工湖供奶牛消暑之用.为了使湖看起来更加真实,FJ决定将湖的 横截面建成N(1 <= N <= 100,000)个连续的平台高低错落的组合状,所有的平台 从左到右按1..N依次编号.当然咯,在湖中注入水后,这些平台都将被淹没. 平台i在设计图上用它的宽度W_i(1 <= W_i <= 1,000

【poj 2386】Lake Counting

Description Due to recent rains, water has pooled in various places in Farmer John's field, which is represented by a rectangle of N x M (1 <= N <= 100; 1 <= M <= 100) squares. Each square contains either water ('W') or dry land ('.'). Farmer

travel hamburg

The area west of Hamburg's central railway station is mainly a shopping area with the streets Spitaler Straße and Mönckebergstraße, leading to Hamburg's town hall. The building behind the city hall is Hamburg's House of Commerce (Börse). Between the

POJ3658Matrix( 双重二分+负数+死循环)

POJ 3658 Matrix 双重二分,wa了一下午,实在不太明白为啥一写二分就会进入死循环. INF要设的大一些,本题设0x3f3f3f3f会wa. 本题有负数, 二分时(l+r)/2与(l+r)>>1的结果有所不同; 如 l=0,r=-1,则 (l+r)/2=0,而(l+r)>>1=-1,而我们需要的正确答案是-1,所以第一种二分必须写成(l+r)>>1 以下两种二分可过: (l+r)>>1 /* * FillName: 二重二分 * Created: