51nod1065(stl/sort)

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1065

题意:中文题诶~

思路:

解法1:set容器,将所有前缀和存储到set和sum数组里,再用set.upper_bound()查找sum[i]后面第一个大于sum[i]的元素,那么他们的差就是第i个元素开头的最小正子段和.然后再将sum[i]从set里面删除,不然会影响后面的查询嘛.遍历所有i就得到我们要的答案啦;

代码:

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 #define MAXN 50010
 4 using namespace std;
 5
 6 const int inf=0x3f3f3f3f;
 7 ll sum[MAXN];
 8 set<ll> st;
 9
10 int main(void){
11     int n;
12     ll x, ans=inf;
13     scanf("%d", &n);
14     for(int i=1; i<=n; i++){
15         scanf("%lld", &x);
16         sum[i]=sum[i-1]+x;
17         st.insert(sum[i]);
18     }
19     st.insert(0);
20     set<ll>::iterator it;
21     for(int i=0; i<n; i++){
22         it=st.upper_bound(sum[i]);
23         if(it!=st.end()){
24             ans=min(ans, *it-sum[i]);
25         }
26         st.erase(sum[i]);
27     }
28     cout << ans << endl;
29     return 0;
30 }

解法2:将前缀和及其下标存储到pair对组(结构题也行啦)里;再以前缀和为权值sort一下,那么我们不难想到如果p[j].first>p[i].first&&p[j].second>p[i].second --条件1 的话p[j].fisrt-p[i].first 就是一段和为正数的子段的和.又因为我们已经给p排过序了,所以i,j越接近,那么得到的子段和就越小,很自然我们会想到j=i+1的情况.问题是对于j=i+1的情况上述条件1一定满足么?或者说最优解一定是来自j=i+1的情况里么?

答案是肯定的,并且我们不难证明它:我们假设排序后顺序为 i, k, j,i和j满足条件1,i和k 不满足条件1, 即:

p[j].second>p[i].second,p[k].second<p[i].second, 所以有:p[j].second>p[k].second,很显然k和j满足条件1并且k和j能比i和j产生更优的解;

所以我们只要考虑j=i+1的情况即可.

此外我们还要注意两点:1.我们排序后得到是p[i+1].first>=p[i].first 而非 p[i+1].first>p[i].first;

           2.我们还要考虑p[i].first本身的值,即从第1个元素到第i个元素的和的情况

代码:

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 #define MAXN 50010
 4 using namespace std;
 5
 6 const int inf=0x3f3f3f3f;
 7 pair<ll, int> p[MAXN];
 8
 9 int main(void){
10     int n;
11     ll x, ans=inf;
12     scanf("%d", &n);
13     for(int i=1; i<=n; i++){
14         scanf("%lld", &x);
15         p[i].first=p[i-1].first+x;
16         p[i].second=i;
17     }
18     sort(p, p+n+1);
19     for(int i=0; i<n; i++){
20         if(p[i].first>0){
21             ans=min(ans, p[i].first);
22         }
23         if(p[i+1].second>p[i].second&&p[i+1].first>p[i].first){
24             ans=min(ans, p[i+1].first-p[i].first);
25         }
26     }
27     cout << ans << endl;
28     return 0;
29 }
时间: 2024-12-26 15:30:56

51nod1065(stl/sort)的相关文章

stl sort分析

最近写代码,无意中发现了一个坑,关于自定义比较函数的stl sort函数的坑,于是记录下来. 先贴代码: 1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 5 struct finder 6 { 7 bool operator()(int first, int second){return first <= second;} 8 } my_finder; 9 10 int main

c++ STL sort struct comp

详细解说 STL 排序(Sort) http://www.cppblog.com/mzty/archive/2005/12/15/1770.html 详细解说 STL 排序(Sort) 作者Winter 详细解说 STL 排序(Sort) 0 前言: STL,为什么你必须掌握 1 STL提供的Sort 算法 1.1 所有sort算法介绍 1.2 sort 中的比较函数 1.3 sort 的稳定性 1.4 全排序 1.5 局部排序 1.6 nth_element 指定元素排序 1.7 partit

STL sort()函数

C++之所以得到这么多人的喜欢,是因为它既具有面向对象的概念,又保持了C语言高效的特点.STL 排序算法同样需要保持高效.因此,对于不同的需求,STL提供的不同的函数,不同的函数,实现的算法又不尽相同. 1.1 所有sort算法介绍 所有的sort算法的参数都需要输入一个范围,[begin, end).这里使用的迭代器(iterator)都需是随机迭代器(RadomAccessIterator), 也就是说可以随机访问的迭代器,如:it+n什么的.(partition 和stable_parti

STL sort

STL的sort()算法,数据量大时采用Quick Sort,分段递归排序,一旦分段后的数据量小于某个门槛,为避免Quick Sort的递归调用带来过大的额外负荷,就改用Insertion Sort.如果递归层次过深,还会改用Heap Sort.本文先分别介绍这个三个Sort,再整合分析STL sort算法(以上三种算法的综合) -- Introspective Sorting(内省式排序). 一.Insertion Sort Insertion Sort是<算法导论>一开始就讨论的算法.它的

STL sort 源码解析

前言 --本文整理自<STL源码解析> 虽然源码解析的代码比较老但是核心思想并没有太多变化并且直接看源码有太多细节我又看不懂最新的. 简介 sort接受两个RandomAccessIterators(随机存储迭代器),然后将区间内的所有元素以渐増的方式由小到大重新排列,第二个版本允许用户指定一个仿函数作为排序标准,STL所有关系型容器都拥有自动排序功能,不需要sort,stack,queue,priority-queue都有特别出入口,不允许排序,剩下vector,deque和list,前两者

STL Sort Algorithm

这个星期看了侯捷先生<STL 源码剖析>算法部分,基本看完了,其中算法比较多,我就重点下Sort在SGI STL中的实现. 1. sort 函数的实现是这样的: template <class RandomAccessIterator> inline void sort(RandomIAccessIterator first , RandomAccessIterator last> { if ( first != last) { __introsort_loop(fisrt,

STL sort函数的用法

sort在STL库中是排序函数,有时冒泡.选择等O(N^2)算法会超时时,我们可以使用STL中的快速排序O(N log N)完成排序 sort在<algorithm>库里面,原型如下: template <class RandomAccessIterator> void sort ( RandomAccessIterator first, RandomAccessIterator last ); template <class RandomAccessIterator, cl

STL sort 的用法

sort的原型: default (1) template <class RandomAccessIterator> void sort (RandomAccessIterator first, RandomAccessIterator last); custom (2) template <class RandomAccessIterator, class Compare> void sort (RandomAccessIterator first, RandomAccessIt

nyoj 41-三个数从小到大排序(STL --&gt; sort(a, a+n) 升序)

41-三个数从小到大排序 内存限制:64MB 时间限制:3000ms Special Judge: No accepted:31 submit:44 题目描述: 现在要写一个程序,实现给三个数排序的功能 输入描述: 输入三个正整数 输出描述: 给输入的三个正整数排序 样例输入: 复制 20 7 33 样例输出: 7 20 33 分析: 直接使用STL库中的sort函数进行排序 C/C++代码实现(AC): #include <iostream> #include <algorithm&g