cf599C Day at the Beach(区间合并)

C. Day at the Beach
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
One day Squidward, Spongebob and Patrick decided to go to the beach. Unfortunately, the weather was bad, so the friends were unable to ride waves. However, they decided to spent their time building sand castles.

At the end of the day there were n castles built by friends. Castles are numbered from 1 to n, and the height of the i-th castle is equal to hi. When friends were about to leave, Squidward noticed, that castles are not ordered by their height, and this looks ugly. Now friends are going to reorder the castles in a way to obtain that condition hi ≤ hi + 1 holds for all i from 1 to n - 1.

Squidward suggested the following process of sorting castles:

Castles are split into blocks — groups of consecutive castles. Therefore the block from i to j will include castles i, i + 1, …, j. A block may consist of a single castle.
The partitioning is chosen in such a way that every castle is a part of exactly one block.
Each block is sorted independently from other blocks, that is the sequence hi, hi + 1, …, hj becomes sorted.
The partitioning should satisfy the condition that after each block is sorted, the sequence hi becomes sorted too. This may always be achieved by saying that the whole sequence is a single block.
Even Patrick understands that increasing the number of blocks in partitioning will ease the sorting process. Now friends ask you to count the maximum possible number of blocks in a partitioning that satisfies all the above requirements.

Input
The first line of the input contains a single integer n (1 ≤ n ≤ 100 000) — the number of castles Spongebob, Patrick and Squidward made from sand during the day.

The next line contains n integers hi (1 ≤ hi ≤ 109). The i-th of these integers corresponds to the height of the i-th castle.

Output
Print the maximum possible number of blocks in a valid partitioning.

Sample test(s)
input
3
1 2 3
output
3
input
4
2 1 3 2
output
2
Note
In the first sample the partitioning looks like that: [1][2][3].
这里写图片描述

In the second sample the partitioning is: [2, 1][3, 2]
这里写图片描述

就是给一个序列,然后划分区间,每个区间自己排序之后的结果和整体排序的结果是一样的,问最多划分多少区间。

当时按照区间的思想想了一下,每个数排序之后都是有位置的,那么这个数现在的位置到排序后的位置就是这个数的最短区间。
然后猜想一下(因为有的数会有多个)
找出这个数的上下界up,down
1.如果现在位置在上下界内,区间就是[i,i];
2.如果在下界以下,就是[i,down];
3.上界以上,就是[up,i];
然后得到n个区间,接着区间合并,看有多少个独立区间。

当时没有完整证明出来,现在还是想不通,只能从yy角度上想通一点,找了半天也没有反例,而且终测也过了,看样应该有道理,再想想吧。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<string>
#include<cmath>
#include<set>
#include<map>
#include<vector>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 1005;
int a[100005],b[100005];
struct Node
{
    int l,r;
}node[100005];
bool cmp(Node a,Node b)
{
    if(a.l == b.l)return a.r < b.r;
    return a.l < b.l;
}
int main()
{
    #ifdef LOCAL
    freopen("C:\\Users\\ΡΡ\\Desktop\\in.txt","r",stdin);
    //freopen("C:\\Users\\ΡΡ\\Desktop\\out.txt","w",stdout);
    #endif // LOCAL
    int n;
    scanf("%d",&n);
    for(int i = 1;i <= n;i++)
        scanf("%d",&a[i]);
    for(int i = 1;i <= n;i++)b[i] = a[i];
    sort(b + 1,b + 1 + n);
    for(int i = 1;i <= n;i++)
    {
        int down = lower_bound(b + 1,b + 1 + n,a[i]) - b;
        int up = upper_bound(b + 1,b + 1 + n,a[i]) - b - 1;
        if(down <= i &&i <= up)node[i].l = node[i].r = i;
        else if(i < down)
        {
            node[i].l = i;node[i].r = down;
        }
        else
        {
            node[i].r = i;node[i].l = up;
        }
    }
    /*for(int i = 1;i <= n;i++)
        cout<<node[i].l<<" "<<node[i].r<<endl;*/
    sort(node + 1,node + 1 + n,cmp);
    int ans,l,r;
    ans = 1;l = node[1].l;r = node[1].r;
    for(int i = 2;i <= n;i++)
    {
        if(node[i].l > r)
        {
            ans++;l = node[i].l;r = node[i].r;
        }
        else
            r = max(r,node[i].r);
    }
    printf("%d\n",ans);
    return 0;
}
在编程竞赛问题CF1384B2(Koa和海滩)中,我们需要判断Koa是否能从海滩的一端走到另一端,而不会被潮水淹没。问题的核心在于模拟潮水的变化和Koa的移动策略。 ### 解题思路 1. **潮汐变化**: - 潮水每单位时间上涨一次,具体水位变化遵循公式 $ water = \lfloor t / x \rfloor $,其中 `t` 是当前时间,`x` 是潮汐周期。 - 在每个时间点,潮水会先下降,然后Koa移动。这意味着Koa在潮水下降后可以尝试前进。 2. **模拟行走过程**: - Koa在每一秒只能移动一个单位距离。 - 如果当前位置的水深在潮水下降后仍然小于等于0,则Koa可以安全地前进。 - 如果在任何时刻,水深大于0,则Koa无法前进,必须等待潮水下降。 3. **关键条件**: - 初始时,所有位置的水深为 `d[i] = a[i] - (t - 0)`,其中 `a[i]` 是该位置的沙堡高度。 - 在每一步中,潮水下降 `1`,即 `t` 增加 `1`,水深随之减少。 4. **终止条件**: - 如果Koa能够成功走到对岸(即所有位置都安全通过),则输出 "Yes"。 - 否则,输出 "No"。 ### 代码实现 ```python def can_cross_beach(n, x, a): t = 0 # 初始时间 for i in range(n): # 每次进入新的位置时,潮水已经下降 t 次 # 计算当前水深:a[i] - t if a[i] - t <= 0: # 如果当前位置的水深为0或负数,可以站立 pass else: # 如果水深大于0,无法站立,必须等待潮水下降 # 计算需要等待的时间,使得 a[i] - (t + wait) <= 0 wait = a[i] - t t += wait # 更新时间 if i == n - 1: return "Yes" t += 1 # 每秒钟只能移动一步 return "Yes" # 输入部分 n, x = map(int, input().split()) a = list(map(int, input().split())) # 调用函数并输出结果 print(can_cross_beach(n, x, a)) ``` ### 解释代码 - **函数 `can_cross_beach`**: - 接受三个参数:`n` 表示海滩的长度,`x` 表示潮汐周期,`a` 是一个列表,表示每个位置的沙堡高度。 - 使用变量 `t` 来跟踪当前时间。 - 遍历每个位置时,检查当前水深是否安全。如果不安全,则计算需要等待的时间 `wait`,并更新时间 `t`。 - 如果Koa能够成功走到对岸,则返回 "Yes";否则返回 "No"。 - **输入部分**: - 读取输入值 `n` 和 `x`,以及沙堡高度列表 `a`。 - 调用 `can_cross_beach` 函数并输出结果。 ### 时间复杂度分析 - **时间复杂度**:`O(n)`,其中 `n` 是海滩的长度。由于我们只需要遍历一次整个海滩,时间复杂度是线性的。 ### 空间复杂度分析 - **空间复杂度**:`O(1)`,除了输入数据外,只使用了常数级别的额外空间。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值