当前位置: 首页 > article >正文

Codeforces div 863C

Problem - C - Codeforces

设定m=n-1

首先,对于a数组的开头与末尾,我们可以证明,他总是等于b数组的开头和结尾

因为如果 a 2 > a 1 a_2>a_1 a2>a1 那么 a 1 a_1 a1也就无法被还原了,所有 { x ∣ x ≤ a 2 } \{x| x\leq a_2\} {xxa2}都是成立的,而此时 b 1 b_1 b1是等于 a 2 a_2 a2的,也就保证了 a 1 a_1 a1一定可以等于 b 1 b_1 b1

同理, a n = b m a_n =b_m an=bm

解法一

对于b数组中的每个数字,是由a数组中左右两个数字取较大值得到的,通过对 a 1 = b 1 a_1 = b_1 a1=b1 a n = b n − 1 a_n = b_n-1 an=bn1 a i = m i n ( b i , b i − 1 ) a_i = min(b_i,b_{i-1}) ai=min(bi,bi1)的实现课复原一个合法的a数组

具体原理如下

考虑一个 1 < i < n 1<i<n 1<i<n a i a_i ai

b i = m a x ( a i , a i − 1 ) b_i = max(a_i,a_{i-1}) bi=max(ai,ai1) b i + 1 = m a x ( a i , a i + 1 ) b_{i+1} = max(a_i,a_i+1) bi+1=max(ai,ai+1)是成立的

我们考虑这样一种情况,也就是 b i , b i − 1 b_i,b_{i-1} bi,bi1均不是a_i原值的时候,即 a i − 1 < a i < a i + 1 a_{i-1} < a_i<a_{i+1} ai1<ai<ai+1,此时 a i a_i ai 无法被还原,也就是说 a i = m i n ( a i − 1 , a i + 1 ) a_i = min(a_{i-1},a_{i+1}) ai=min(ai1,ai+1),即 a i = m i n ( b i , b i − 1 ) a_i = min(b_i,b_{i-1}) ai=min(bi,bi1)

对于其他情况,如 b i = = a i ∣ ∣ b i − 1 = = a i b_i==a_i||b_{i-1} ==a_i bi==ai∣∣bi1==ai, 我们直接取两个值当中的最小值就好。因为通过分析可以发现,原来的值一定为较小值

a i − 1 < a i < a i + 1 a_{i-1} < a_i< a_i+1 ai1<ai<ai+1 b i = a i b_i = a_i bi=ai b i + 1 = a i + 1 b_{i+1} = a_{i+1} bi+1=ai+1 由于 a i < a i + 1 a_i<a_{i+1} ai<ai+1所以 a i a_i ai为其中较小值

由于对称,所以相反的状况下该结论也成立

对于 a i a_i ai在三个值中最大的情况也是成立的因为 b i = b i − 1 = a i b_i=b_i-1 = a_i bi=bi1=ai

所以,对它使用结论吧

inline void slove()
{
    cin >> n;
    m = n - 1;

    for (int i = 1; i <= m; i++) cin >> b[i];

    a[n] = b[m];
    a[1] = b[1];
    for (int i = m; i>1; i--)
        a[i] = min(b[i - 1], b[i]);

    for (int i = 1; i <= n; i++) printf("%lld ", a[i]);
    puts("");

    return;
} 

解法二
其实解法二是对解法一的近似,两者是完全相同的,只不过一个用到了min,另一个没有,不过由于思路的完全不同,这里还是讲一下

从尾遍历,对于每一个 b i b_i bi,如果出现 b i > b i − 1 b_i>b_{i-1} bi>bi1的情况,需要重复一遍 b i b_i bi,再添加 b i − 1 b_{i-1} bi1

inline void slove()
{
    cin >> n;
    m = n - 1;

    for (int i = 1; i <= m; i++) cin >> b[i];

    a[n] = b[m];
    a[1] = b[1];
    for (int i = m; i > 1; i--)
    {
        if (b[i - 1] > b[i])
        {
            a[i] = b[i];
            a[i - 1] = b[i - 1];
        }
        else a[i] = b[i - 1];
    }

    for (int i = 1; i <= n; i++) printf("%lld ", a[i]);
    puts("");

    return;
}

http://www.kler.cn/a/6358.html

相关文章:

  • 《Swift 字面量》
  • 选择FPGA开发,学历是硬性要求吗?
  • SDMTSP:粒子群优化算法PSO求解单仓库多旅行商问题,可以更改数据集和起点(MATLAB代码)
  • 【时间之外】IT人求职和创业应知【74】-运维机器人
  • 使用 perf 工具进行性能分析
  • 服务器压力测试怎么做
  • C++ unordered_map容器所有的函数使用方法
  • 【Ruby学习笔记】6.Ruby 注释及判断
  • 剑指 Offer 56 - I. 数组中数字出现的次数
  • Android物理按键事件处理
  • springboot 数据库应用
  • .NET Core 中实现分布式事务的几种方案
  • 理想汽车的雷达在无人陵园内看到鬼?网友:按一下喇叭看会不会聚过来!
  • 基于SpringBoot开发的人事管理系统
  • Python 高级编程(文件操作)
  • TCP / IP 模型
  • AtCoder Beginner Contest 296 (A~D)
  • 虚拟机与主机互传文件
  • 【C++】哈希
  • C++初阶—string类(1)
  • web前端面试题之webpack和其他
  • spring七种事务传递机制及其原理
  • 会C#如何学习Python的几个关键点
  • pytorch安装和测试
  • MyBatis
  • 注册谷歌账户教程--解决注册谷歌账户“此电话号码无法用于进行验证”问题--亲测已解决--谷歌账户注册全流程