「一本通 1.3 例 5」weight]
「一本通 1.3 例 5」weight
题面
给定原数列 \(a_1,a_2,a_n\) ,给定每个数的前缀和以及后缀和,并且打乱顺序。
给出一个集合 \(S\) 要求从集合 \(S\) 中找到合适的数,满足给定的所有数例前缀和和后缀和,答案保证最小的
思路
很多人上来没有思路,不知从何搜起
简单讲就是找到正确的搜索顺序,往里面放数就好了
他不是有前缀和也有后缀和嘛~,而且还是混着的,
那么你就直接排序,然后安排两个指针 \(L\) 和 \(R\) 的表示左边和右边,
记录每个 \(L\) 的前缀和 和 \(R\) 的后缀和,然后用当前的你所枚举的(题中给出的混杂数列)\(A[k]\) 相减,即 \(A[k] - Sum[L] \ 或者
A[k] - Sum[r]\) ,只要相减的差在给定集合 \(S\) 里,直接搜索下一层,两个指针肯定会跑到一起,最后再判断答案合不合限定范围就可以了 \(Over\)
-----------------------------------------------------------------------分割线----------------------------
详细的说 就是通过给定的条件,找到约束条件,进而说明我为什么要选择上面的搜索顺序和思路
- 令 满足要求的 \(SumL_i\) (原数列 \(N\),右同),表示位置 \(i\) 的前缀和 ,
- 令 满足要求的 \(SumL_j\) 表示位置 \(j\) 的后缀和,
- 令 \(ans_i\) 为答案数列
不难发现
可以将打乱的先排序,最后的数\(Max\)显然就是 \(SumL_n\) 和 \(SumR_n\), 最小的数 \(Min\) 要不是最左边,要不是最右边。(剪枝1)
我们从已知条件的数据当中任意取出两个数的时候,只会出现以下两种情况:

当为一种情况时,即都为前缀和或后缀和(后面的前缀和和后缀和统一用 \(Sum\) 表示,以为我说的是第一种情况),
那么 \(Sum_{i+1} - Sum_i\) 就是位置 \(i\) 的 \(ans[i]\) ,所以我们找到了达成要求的条件,即知道满足 两个\(A[k] - A[p] (k,p均为变量)\) 的差值在集合 \(S\) 中,那么就找到了当前正确的 \(Sum_i\)
凭着是上面的条件,我们可以将枚举 \(A[k]\) ,并放入相应的位置中,那么他放的可能无非就两种,一是放在左边,二是放在右边,那么枚举时记录一下左右当前位置 \(L\) 和 \(R\) (即在 \(L-R\) 范围内都是还没填上数的),一直搜到 \(L == R\) ,输出就行,(因为开始我先进行了排序,所以找到的答案一定为最小序列的)
终于说完了~累死了
Code
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
//#define int long long
const int manx = 1e7;
const int maxm = 1e8;
const int inf = 0x3f3f3f3f;
int read(){
char c = getchar();int x = 0,f = 1;
for( ;!isdigit(c);c = getchar()) if(c == '-') f = -1;
for( ;isdigit(c);c = getchar()) x = x * 10 + (c ^ 48);
return x * f;
}
int a[manx],ans[manx];
bool vis[manx],flag;
int n, m, i;
void dfs(int k ,int l ,int r ,int sum_l ,int sum_r){
/*
k 表示枚举的数据给出的已经排完序的A[k]
l,r 表示搜到的左右边界(l,r是我们要填数的其中一个,所以记录的都是他们前一个或后一个的和),
sum_l,sum_r 分别记录的是l-1的前缀和,r+1的后缀和,
*/
if(flag == true) return;//完成深搜
if(l == r){
if(vis[a[k] - sum_l] == false && vis[a[k] - sum_r] == false) return;
if( a[2 * n] - sum_l - sum_r < 1 || a[2 * n] - sum_l - sum_r > 500) return; //这里被卡,防止在加数的先选的大的,剩下个小的,之后一相减就成负数了
ans[l] = a[2 * n] - sum_l - sum_r;
for(i = 1;i <= n; i++) printf("%d ",ans[i]);
cout<<'\n';
flag = true;
}
if(vis[a[k] - sum_l] == true ){
ans[l] = a[k] - sum_l;
dfs(k + 1 ,l + 1 ,r ,a[k] ,sum_r);
}
if(vis[a[k] - sum_r] == true ){
ans[r] = a[k] - sum_r;
dfs(k + 1 ,l , r - 1,sum_l , a[k]);
}
}
int main(){
//freopen("dd.in","r",stdin);
//freopen("dd.out","w",stdout);
n = read();
for(i = 1;i <= n * 2;i ++) a[i] = read();
sort(a + 1 ,a + 1 + n * 2);
m = read();
for(i = 1;i <= m; i++) {
int x = read();
vis[x] = true;//表示x这数在不在集合S当中
}
dfs(1,1,n,0,0);
return 0;
}
最累的题解了~
「一本通 1.3 例 5」weight]的更多相关文章
- 「LOJ#10051」「一本通 2.3 例 3」Nikitosh 和异或(Trie
题目描述 原题来自:CODECHEF September Challenge 2015 REBXOR 1≤r1<l2≤r2≤N,x⨁yx\bigoplus yx⨁y 表示 ...
- LOJ#10064. 「一本通 3.1 例 1」黑暗城堡
LOJ#10064. 「一本通 3.1 例 1」黑暗城堡 题目描述 你知道黑暗城堡有$N$个房间,$M$条可以制造的双向通道,以及每条通道的长度. 城堡是树形的并且满足下面的条件: 设$D_i$为如果 ...
- 「LOJ#10043」「一本通 2.2 例 1」剪花布条 (KMP
题目描述 原题来自:HDU 2087 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢? 输入格式 输入数据 ...
- LOJ #10131 「一本通 4.4 例 2」暗的连锁
LOJ #10131 「一本通 4.4 例 2」暗的连锁 给一棵 \(n\) 个点的树加上 \(m\) 条非树边 , 现在需要断开一条树边和一条非树边使得图不连通 , 求方案数 . $n \le 10 ...
- 「LOJ#10050」「一本通 2.3 例 2」The XOR Largest Pair (Trie
题目描述 在给定的 $N$ 个整数 $A_1,A_2,A_3...A_n$ 中选出两个进行异或运算,得到的结果最大是多少? 输入格式 第一行一个整数$N$. 第二行$N$个整数$A_i$. 输出格式 ...
- 「LOJ#10072」「一本通 3.2 例 1」Sightseeing Trip(无向图最小环问题)(Floyd
题目描述 原题来自:CEOI 1999 给定一张无向图,求图中一个至少包含 333 个点的环,环上的节点不重复,并且环上的边的长度之和最小.该问题称为无向图的最小环问题.在本题中,你需要输出最小环的方 ...
- 「LOJ#10034」「一本通 2.1 例 2」图书管理 (map
题目描述 图书管理是一件十分繁杂的工作,在一个图书馆中每天都会有许多新书加入.为了更方便的管理图书(以便于帮助想要借书的客人快速查找他们是否有他们所需要的书),我们需要设计一个图书查找系统. 该系统需 ...
- Loj 10115 「一本通 4.1 例 3」校门外的树 (树状数组)
题目链接:https://loj.ac/problem/10115 题目描述 原题来自:Vijos P1448 校门外有很多树,学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的 ...
- LOJ #10222. 「一本通 6.5 例 4」佳佳的 Fibonacci
题目链接 题目大意 $$F[i]=F[i-1]+F[i-2]\ (\ F[1]=1\ ,\ F[2]=1\ )$$ $$T[i]=F[1]+2F[2]+3F[3]+...+nF[n]$$ 求$T[n] ...
随机推荐
- @RequestBody,@RequestParam请求数据接收数据
一. @RequestBody 注解 @RequestBody是用于解析body中的json内容,对于我们使用时候我们需要指定Content-Type参数为application/json,标识我们需 ...
- web项目报错 无法解析,丢失包 是缺少本地运行jre
1.通过build path 添加add Library 2.添加jre
- IntelliJ IDEA错误: 源值1.5已过时,将在未来所有版本中删除
参考:http://www.jianshu.com/p/451271c4de11
- 前台生成JSON
方法一 :在后台需要转换String - json let param = new URLSearchParams(); param.append('username', this.username) ...
- Markdown高级使用之流程图
流程图在Markdown中的的表现形式就是代码块,代码块语言标记为mermaid.主要内容大体分为:方向.节点.节点间的连接关系,下面就围绕这三个点来整理. mermaid支持流程图.甘特图和时序图, ...
- Appium自动化如何控制多设备并行执行
前言: 如何做到,控制多设备并行执行测试用例呢. 思路篇 我们去想下,我们可以获取参数的信息,和设备的信息,那么我们也可以针对每台设备开启不一样的端口服务.那么每个服务都对应的端口,我们在获取设备列 ...
- idea配置scala编写spark wordcount程序
1.创建scala maven项目 选择骨架的时候为org.scala-tools.archetypes:scala-aechetype-simple 1.2 2.导入包,进入spark官网Docum ...
- 杭电OJ2005---第几天?(c++)
Problem Description 给定一个日期,输出这个日期是该年的第几天. Input 输入数据有多组,每组占一行,数据格式为YYYY/MM/DD组成,具体参见sample input ,另外 ...
- Java基础--接口回调(接口 对象名 = new 类名)理解
接口 对象名1 = new 类名和类名 对象名2 = new 类名的区别是什么? 实例 /** *Person.java 接口 */ public interface Person { void in ...
- C# 中的 null 包容运算符 “!” —— 概念、由来、用法和注意事项
在 2020 年的最后一天,博客园发起了一个开源项目:基于 .NET 的博客引擎 fluss,我抽空把源码下载下来看了下,发现在属性的定义中,有很多地方都用到了 null!,如下图所示: 这是什么用法 ...