K签个到(贪心)第十五届中北大学算法与程序设计竞赛

题目链接:https://ac.nowcoder.com/acm/contest/5188/K

题目大意:

给定 n个正整数:a1,a2...an−1,an。每次操作可以选择数组中任意一个数加上或减去其下标。
求 m次操作后,数组中最大值与最小值的差最大可能是多少。
(1<=n<=100000,0<=m<=100000)
(−100000<=ai<=100000)

题解:贪心

直觉就是 m次操作在同一个数上是最优的

答案就是a[i]+m*i-a(min)和a(max)-(a[i]-i*m)中更大的那一个

代码:

#include<iostream>
#include<cstdio> 
#include<cstring>
#include<algorithm>
#define N 100009
#define LL long long
using namespace std;
 
LL n,m;

struct P
{
    LL x,id; 
}a[N]; 

bool cmp(P c,P d)
{
    return c.x<d.x;
}

int main()
{
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++)
    {
    //    scanf("%d",&a[i].x);
        cin>>a[i].x;
        a[i].id=i;
    }
    if(n==1)
    {
        cout<<'0';
        return 0;
    }
    sort(a+1,a+n+1,cmp);
//    LL mx=-10000000000,mx_;
//    LL mn=10000000000,mn_;
    LL mx=a[1].x+m*a[1].id;
    LL mn=a[1].x-m*a[1].id; 
    for(LL i=1;i<=n;i++)
    {
        if(a[i].x+m*a[i].id>mx) mx=a[i].x+m*a[i].id;
        if(a[i].x-m*a[i].id<mn) mn=a[i].x-m*a[i].id;
    }
  //  cout<<mx<<"---"<<mn<<endl;
    LL ans1=mx-a[1].x;
    LL ans2=a[n].x-mn;
    if(ans1-ans2>0) cout<<ans1;
    else cout<<ans2;
    return 0;
}
 /*我傻了*/
View Code

 

posted @ 2021-03-04 18:57  ANhour  阅读(83)  评论(0)    收藏  举报