话不多说,直接看题:

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

当k

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

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

下面是AC代码:

#include

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

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<

}

接题:

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

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

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

下面是AC代码:

#include

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

if(m==0){

LL res=0;

for(int i=0;i

cout<

return 0;

}

sort(a,a+k);

LL res=a[k-1]-a[0];

for(int i=1;i

cout<

}

接题:

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

那么怎么求?我们不妨假设a[0]

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

那么怎么走最优?

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

下面是AC代码:

#include

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<

}

}

好文阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。