2015年百度之星初赛(1) --- C 序列变换

序列变换

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 158    Accepted Submission(s): 83

Problem Description

给定序列$A = \{A_1, A_2,...,A_n\}$, 要求改变序列A中的某些元素,形成一个严格单调的序列B(严格单调的定义为:$B_i < B_{i+1}, 1 \leq i < N$)。

我们定义从序列A到序列B变换的代价为$cost(A, B) = max(|A_i - B_i|) (1 \leq i \leq N)$。

请求出满足条件的最小代价。

注意,每个元素在变换前后都是整数。

Input

第一行为测试的组数$T(1 \leq T \leq 10)$.

对于每一组:
第一行为序列A的长度$N(1 \leq N \leq 10^5)$,第二行包含N个数,$A_1, A_2, ...,A_n$.
序列A中的每个元素的值是正整数且不超过$10^6$。

Output

对于每一个测试样例,输出两行:

第一行输出:"Case #i:"。i代表第 i 组测试数据。

第二行输出一个正整数,代表满足条件的最小代价。

Sample Input

2
2
1 10
3
2 5 4

Sample Output

Case #1:
0
Case #2:
1

Problem‘s Link:   http://acm.hdu.edu.cn/showproblem.php?pid=5248



Mean:

analyse:

二分答案 + 贪心验证

Time complexity: O(n)

Source code: 

/*
* this code is made by crazyacking
* Verdict: Accepted
* Submission Date: 2015-05-30-22.26
* Time: 0MS
* Memory: 137KB
*/
#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#define  LL long long
#define  ULL unsigned long long
using namespace std;
const int MAXN=100010;

int num[MAXN],n,T,tmp[MAXN];
inline bool check(int l){
    for(int i=1;i<=n;i++)
    tmp[i]=num[i];
    tmp[1]=num[1]-l;
    for(int i=2;i<=n;i++)
        if(num[i]+l<=tmp[i-1])
            return false;
        else
            tmp[i]=max(num[i]-l,tmp[i-1]+1);
    return true;
}
int main()
{
    scanf("%d",&T);
    for (int Rt=1;Rt<=T;Rt++)
        {
        scanf("%d",&n);
        cout<<"Case #"<<Rt<<‘:‘<<endl;
        for(int i=1;i<=n;i++) scanf("%d",&num[i]);
        int l=0,r=1000000,ans=0;
        while(l<=r){
            int mid=(l+r)>>1;
            if(check(mid)){
                ans=mid;
                r=mid-1;
            }else{
                l=mid+1;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

时间: 2024-12-23 21:24:11

2015年百度之星初赛(1) --- C 序列变换的相关文章

二分搜索 2015百度之星初赛1 1003 序列变换

题目传送门 1 /* 2 二分搜索:在0-1e6的范围找到最小的max (ai - bi),也就是使得p + 1 <= a[i] + c or a[i] - c 3 比赛时以为是贪心,榨干智商也想不出来:( 4 */ 5 #include <cstdio> 6 #include <algorithm> 7 #include <cstring> 8 #include <cmath> 9 #include <iostream> 10 using

2015百度之星初赛2 1005 序列变换(LIS变形)

LIS(非严格):首先我想到了LIS,然而总觉得有点不对:每个数先减去它的下标,防止下面的情况发生:(转载) 3 加入序列是1,2,2,2,3,这样求上升子序列是3,也就是要修改2个,但是中间的两个2,变化范围又不能超过(1,3) 4 那么这样求的也就不对,但是减掉之后,相当于给中间重复的数留下了修改的空间 5 解释下为什么可以减而保持正确性:因为题目所求时严格递增,假设是2,3, 4,那么变成1, 1, 1,所以在LIS里非严格递增就可以了 6 这也是为什么要在upper_bound的位置插入

2015年百度之星初赛(1) --- D KPI

KPI Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 170    Accepted Submission(s): 59 Problem Description 你工作以后, KPI 就是你的全部了. 我开发了一个服务,取得了很大的知名度.数十亿的请求被推到一个大管道后同时服务从管头拉取请求.让我们来定义每个请求都有一个重要值.我的KP

2015年百度之星初赛(1) --- B 找连续数

找连续数 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 179    Accepted Submission(s): 65 Problem Description 小度熊拿到了一个无序的数组,对于这个数组,小度熊想知道是否能找到一个k 的区间,里面的 k 个数字排完序后是连续的. 现在小度熊增加题目难度,他不想知道是否有这样的 k 的区

2015年百度之星初赛(1) --- F 矩形面积

矩形面积 Problem Description 小度熊有一个桌面,小度熊剪了很多矩形放在桌面上,小度熊想知道能把这些矩形包围起来的面积最小的矩形的面积是多少. Input 第一行一个正整数 T,代表测试数据组数($1 \leq T \leq 20$),接下来 T 组测试数据. 每组测试数据占若干行,第一行一个正整数 $N(1 \leq N < \leq 1000)$,代表矩形的数量.接下来 N 行,每行 8 个整数$x_1, y_1, x_2, y_2, x_3, y_3, x_4, y_4$

2015年百度之星初赛(1) --- 超级赛亚ACMer

超级赛亚ACMer Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description 百小度是一个ACMer,也是一个超级赛亚人,每个ACMer都有一个战斗力,包括百小度.?所谓超级赛亚人的定义,是说如果在对抗中刚好接近极限状态,那就会激发斗志,实力提升.? 具体来说,就是百小度现在要接受一些ACMer的挑战了,这些ACMer有n个人,第i个人的战斗力是a[i]

数学 2015百度之星初赛2 HDOJ 5255 魔法因子

题目传送门 1 /* 2 数学:不会写,学习一下这种解题方式:) 3 思路:设符合条件的数的最高位是h,最低位是l,中间不变的部分为mid,由题意可得到下面的公式(这里对X乘上1e6用a表示,b表示1e6) 4 (h*power+l+mid)*a = (l*power+h+mid)*b 5 可推得:mid = ((h*power+l) * a - (l*power+h) * b) / (a - b); 6 所以可以枚举h,l然后求mid,注意mid的最低位一定是0,因为留出最低位加l或者h 7

LIS 2015百度之星初赛2 HDOJ 5256 序列变换

题目传送门 1 /* 2 LIS(非严格):首先我想到了LIS,然而总觉得有点不对:每个数先减去它的下标,防止下面的情况发生:(转载) 3 加入序列是1,2,2,2,3,这样求上升子序列是3,也就是要修改2个,但是中间的两个2,变化范围又不能超过(1,3) 4 那么这样求的也就不对,但是减掉之后,相当于给中间重复的数留下了修改的空间 5 解释下为什么可以减而保持正确性:因为题目所求时严格递增,假设是2,3, 4,那么变成1, 1, 1,所以在LIS里非严格递增就可以了 6 这也是为什么要在upp

二分查找 2015百度之星初赛1 1001 超级赛亚ACMer

题目传送门 1 /* 2 二分找到不大于m的最大的数,记做p,只要a[p] + k <= a[p+1]就继续 3 注意:特判一下当没有比m小的数的情况:) 4 */ 5 #include <cstdio> 6 #include <cstring> 7 #include <cmath> 8 #include <algorithm> 9 using namespace std; 10 11 typedef long long ll; 12 13 const