0
点赞
收藏
分享

微信扫一扫

JVM垃圾收集——相关概念

话不多说,直接看题:

首先我们大致分析一下,先排序一下,K==n,那就全部选。

当k<n时,k是偶数,那么结果一定非负,因为假如负数的个数有偶数个,那么我们成对选它,假如是奇数个,我们就把某一个负数选出,再成对选即可。

若k是奇数,那么所有数均负,那么答案《0,如果至少存在一个非负数,那我们先选一个非负数,然后问题就转化成了上一个形式。

因此我们排一下序,假如k是偶的,那么我们从两端成对的选,k是奇数,那么一定先选正的(若选负的那么后面也是选奇数个,这样就没有区别了),接下来就是刚才的问题了。

下面是AC代码:

#include<bits/stdc++.h>
using namespace std;
const int N=100010,mod=1e9+9;
typedef long long LL;
int n,k;
int a[N];
int main(){
    cin>>n>>k;
    for(int i=0;i<n;i++) scanf("%d",&a[i]);
    sort(a,a+n);
    int res=1;
    int l=0,r=n-1;
    int sign=1;

    if(k%2){
        res=a[r--];
        k--;
        if(res<0) sign=-1;
    }
    while(k){
        LL x=(LL)a[l]*a[l+1],y=(LL)a[r-1]*a[r];
        if(x*sign>y*sign){
            res=x%mod*res%mod;
            l+=2;
        }
        else{
            res=y%mod*res%mod;
            r-=2;
        }
        k-=2;
    }
    cout<<res;
}

接题:

首先,后缀表达式也可以实现括号操作,首先假如没有负号,那么都是直接相加。

同时我们可以把减号从M变成1(1-(a-b-c---)),最多有N+M个减号。

因此我们减一个最小值,同时必须加最大值(第一个一定是正的),其他加绝对即可。

下面是AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=200010;
int n,a[N],m;
int main(){
    cin>>n>>m;
    int k=n+m+1;
    for(int i=0;i<k;i++) scanf("%d",&a[i]);
    
    if(m==0){
        LL res=0;
        for(int i=0;i<k;i++) res+=a[i];
        cout<<res;
        return 0;
    }
    sort(a,a+k);
    LL res=a[k-1]-a[0];
    for(int i=1;i<k-1;i++) res+=abs(a[i]);
    cout<<res;
}

接题:

我们不妨看看前缀和,我们会惊奇的发现,我们每一次操作相当于交换一下他和它前面的前缀和,因此问题就转化成了求最大前缀和差值的min,并且两端是固定的,中间一段可以任意交换。

那么怎么求?我们不妨假设a[0]<a[n],同时确定其中的max与min。

此时,我们把图像向y轴投影压缩成一条线段,然后排一下序得到:

那么怎么走最优?

显然我们从S0开始向左两点走一步,即跨一个点走一步是最优的。

下面是AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=300010;
LL a[N],s[N];
bool st[N];
int n;
int main(){
    int t;
    cin>>t;
    while(t--){
        scanf("%d",&n);
        s[0]=0;
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            s[i]=s[i-1]+a[i];
        }
        LL s0=s[0],sn=s[n];
        if(s0>sn) swap(s0,sn);
        sort(s,s+n+1);//注意起点在0上
        for(int i=0;i<=n;i++){
            if(s[i]==s0){
                s0=i;
                break;
            }
        }
        for(int i=0;i<=n;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]=1;
        }
        for(int i=sn;i<=n;i+=2){
            a[r--]=s[i];
            st[i]=1;
        }
        for(int i=0;i<=n;i++){
            if(st[i]==0) a[l++]=s[i];
        }
        LL res=0;
        for(int i=1;i<=n;i++){
            res=max(res,abs(a[i]-a[i-1]));
        }
        cout<<res<<endl;
    }
}
举报

相关推荐

0 条评论