蓝桥杯的一道题:灵能传输 https://www.acwing.com/problem/content/description/1250/

首先是简化操作,将原数组转化为前缀和数组(下标都是从1开始),一次灵能传输对原数组涉及三个数(a[i-1],a[i],a[i+1])的操作,而且操作比较麻烦,但是如果转化成前缀和数组后等价于(s[i-1]与s[i])交换位置。

原来的目标是求a[i]绝对值最小值,那么现在的目标变为求s[i]-s[i-1]的绝对值最大值,其中设计的数有s[0~n]

2.由于对数组可以任意交换位置,经过简单的思考可以得知如果序列单调(后面就说成单增了),那么即为所求,那么对s数组排序即可。

但是存在一个问题,即s[0],s[n]参与最后求s[i]-s[i-1]的绝对值最大值的计算,但是由于题意可知s[0],s[n]是无法移动的,因此在此情况下怎么排序呢?

上面两种方式(这里假设s0 是小于sn的(如果是大于,swap一下就是一样的))

右边更优秀,为何?

简单理解就是由于s0比sn更小,因此左边s0到最大值比右边sn到最大值明显差值会小一些。

现在问题变为如何排成右边这种序列?

答案以代码呈现:

if(s0 > sn) swap(s0, sn);

        sort(s, s + n + 1);

        for(int i = 0; i <= n; i ++ )
if(s[i] == s0)
{
s0 = i;
break;
} for(int i = n; i >= 0; i -- )
if(s[i] == sn)
{
sn = i;
break;
} memset(st, 0,sizeof st);
int l = 0 ,r = n; for(int i = s0; i >= 0; i -= 2)
{
a[l ++ ] = s[i];
st[i] = true;
} for(int i = sn; i <= n; i += 2)
{
a[r -- ] = s[i];
st[i] = true;
} for(int i = 0; i <= n; i ++ )
if(!st[i]) a[l ++ ] = s[i]; LL res = 0; for(int i = 1; i <= n; i ++ ) res = max(res, abs(a[i] - a[i - 1]));

核心就是隔一个一取,为何是隔一个,反证法想一想不隔,或者隔两个是个什么情况(反过来的时候是隔两个,就比一次隔一个反过来也是隔一个大了)可以参见y总视频。

详细分析见:

java代码实现:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays; /**
*
*/
public class Main {
static int N=300000+5;
//细节:由于涉及前缀和再加上数据范围,因此需要long
static long[] a=new long[N];
static long[] sum=new long[N];
static int n;
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String[] line = reader.readLine().split(" ");
int t=Integer.parseInt(line[0]);
while (t--!=0) {
Arrays.fill(a, 0);
Arrays.fill(sum, 0);
line=reader.readLine().split(" ");
n=Integer.parseInt(line[0]);
line=reader.readLine().split(" ");
for (int i = 1; i <= n; i++) {
a[i]=Integer.parseInt(line[i-1]);
}
start();
} }
private static void start() {
for (int i = 1; i <= n; i++) {
sum[i]=sum[i-1]+a[i];
}
//s0开始是记数,后面就是记下标了
long s0=sum[0],sn=sum[n];
if (s0>sn) {
long t=s0;
s0=sn;
sn=t;
}
Arrays.sort(sum,0,n+1);
for (int i = 0; i <= n; i++) {
if (sum[i]==s0) {
s0=i;
//第一次遇到就break,否则赋值之后万一又意外相等了
break;
}
}
for (int i = n; i >= 0; i--) {
if (sum[i]==sn) {
sn=i;
break;
}
}
boolean[] st=new boolean[N];
int l=0,r=n;
//a[i]在计算前缀和之后就没有使用了,因此这里再次使用a来减小数据空间
//跳着读取
for (int i = (int)s0; i >= 0; i-=2) {
a[l++]=sum[i];
st[i]=true;
}
for(int i=(int)sn;i<=n;i+=2){
a[r--]=sum[i];
st[i]=true;
}
for (int i = 0; i <= n; i++) {
if (!st[i]) {
a[l++]=sum[i];
}
} long res=0L;
for (int i = 1; i <= n; i++) {
res=Math.max(res,Math.abs( a[i]-a[i-1]));
}
System.out.println(res);
}
}

AcWing 1248. 灵能传输 蓝桥杯的更多相关文章

  1. (acwing蓝桥杯c++AB组)1.1 递归

    (acwing蓝桥杯c++AB组)1.课程介绍+递归 文章目录 (acwing蓝桥杯c++AB组)1.课程介绍+递归 课程介绍 第一讲 递归与递推 递归 引入 递归的底层调用顺序 例题与练习 课程介绍 ...

  2. 第十届蓝桥杯省赛JavaB组个人题解

    前言 以下的第十届蓝桥杯Java B组省赛的题目题解只是我个人的题解,提供一些解题思路,仅作参考,如有错误,望大家指出,不甚感激,我会及时更改. 试题 A: 组队 ----- 答案:490 [问题描述 ...

  3. 第十届蓝桥杯2019年C/C++ 大学B组省赛试题

    2019年第十届蓝桥杯大赛软件类省赛C/C++大学B组 试题 A:组队 本题总分:5分 [问题描述] 作为篮球队教练,你需要从以下名单中选出 1号位至 5号位各一名球员, 组成球队的首发阵容. 每位球 ...

  4. 2019第十届蓝桥杯C++B组题解(赛后重写的,不确保答案正确性,仅供参考)

    先说一下这次的感受吧,我们考场比较乱,开始比赛了,还有的电脑有故障,(向这些人发出同情),第一次认真参加比赛,真正比赛的时候感觉没有那么正式,很乱,各种小问题,(例如博主就没找到题目在哪里,找到后又不 ...

  5. 第十届蓝桥杯JavaB组省赛真题

    试题 A: 组队 本题总分:5 分 [问题描述] 作为篮球队教练,你需要从以下名单中选出 1 号位至 5 号位各一名球员, 组成球队的首发阵容. 每位球员担任 1 号位至 5 号位时的评分如下表所示. ...

  6. 2017年蓝桥杯B组C/C++决赛题目

    2017年第八届蓝桥杯B组C/C++决赛题目 点击查看2017年蓝桥杯B组C/C++决赛题解     1.36进制 对于16进制,我们使用字母A-F来表示10及以上的数字. 如法炮制,一直用到字母Z, ...

  7. 梳理一下最近准备蓝桥杯时学习DP问题的想法

    学习时间不长,记录的只是学习过程的思路和想法,不能保证正确,代码可以在acwing上AC. 01背包问题: 1.首先是简单的01背包问题 2.先确定状态,f[i][j]表示有第i件物品,时间为j的最大 ...

  8. 2012年 蓝桥杯预赛 java 本科 题目

    2012年 蓝桥杯预赛 java 本科 考生须知: l  考试时间为4小时. l  参赛选手切勿修改机器自动生成的[考生文件夹]的名称或删除任何自动生成的文件或目录,否则会干扰考试系统正确采集您的解答 ...

  9. 蓝桥杯历届试题 地宫取宝 dp or 记忆化搜索

    问题描述 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角,出口在右下角. 小明被带到地宫的入口,国王要求他只能向右或向下行走. 走 ...

随机推荐

  1. 设计一个基于svg的涂鸦组件(一)

    基于svg写了一个涂鸦组件,说项目之前先附上几张效果图: 项目地址:SVGraffiti 由于篇幅问题,本文先总体介绍一下项目的大概情况,重点介绍一下组件间的通信方式. 一.项目说明 该项目是基于we ...

  2. B03. BootstrapBlazor实战 10分钟编写数据库维护项目

    demo演示的是Sqlite驱动,FreeSql支持多种数据库,MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/神通/人大金仓/翰高/华为Ga ...

  3. oracle三个连接配置文件 listener.ora、sqlnet.ora、tnsnames.ora

    关于PLSQL连接ORACLE配置字符串 首先要讲一下下面的一些知识 1.ORACLE_SID:(ORACLE SYSTEM IDENTIFIER) Oracle实例是由SGA和一组后台进程组成的,实 ...

  4. openfeign使用踩坑记录

    1.报ClassNotFound com.netflix.config.CachedDynamicIntProperty问题,原因是spring-cloud-starter-openfeign的spr ...

  5. linux find命令 -mtime参数 根据修改时间查找文件

    命令:find 搜索路径 -mtime n 主要说明n的含义: 例: n=5 "5"指的是前 5~6 天那一天修改的文件 n=-5 "-5"指的是 5 天内修改 ...

  6. CURDATE()与NOW()的区别

    两者都是mysql中的函数,都是得到当前时间,区别是: CURDATE()查询出的是当前天的开始时间点,比如今天是 2015.02.03号,那不管我在今天什么时间点查询,结果都是今天的凌晨,即今天的开 ...

  7. Java学习day5

    API即应用程序编程接口,Java所包含的方法以及类很多,如果要使用他们就得了解这些的API如何使用,因为API多而复杂,我们可以通过帮助文档查询 与c/c++类似,Java通过Scanner类就可以 ...

  8. 『现学现忘』Git基础 — 4、Git下载与安装

    目录 1.Git下载 2.Git在Windows下的详细安装 3.验证Git是否安装成功 1.Git下载 进入官方地址下载Git客户端:https://git-scm.com/download/win ...

  9. acwing刷题-放养又没有完全放养

    题目 一个鲜为人知的事实是,奶牛拥有自己的文字:「牛文」. 牛文由 26 个字母 a 到 z 组成,但是当奶牛说牛文时,可能与我们所熟悉的 abcdefghijklmnopqrstuvwxyz 不同, ...

  10. EFCore 的 DbFirst 模式

    1 前言 EF6 时代,可以通过界面操作,添加数据库实体. EF Core 需要通过 CLI 来进行该操作,具体请参考EF Core官方文档:反向工程. 2 前置条件 PMC 工具(仅限 Visual ...