有n个数,k次操作,每次操作可以将第i个数+x或者-x,输出k次操作后这n个数乘积最小时的数列
题意:
先将这个数列从小到大 排序,如果这个数列中有偶数个负数,那么就尽可能的处理出奇数个负数
然后每次取出绝对值最小的数,负数就-x,正数就+x
这样处理出来的就是乘积最小的
#include <bits/stdc++.h>
using namespace std;
#define ll __int64
const int N=2e5+10;
struct node{
ll a, aa;
int id;
friend bool operator < (const node n1, const node n2){
return n1.aa > n2.aa;
}
}arr[N];
priority_queue<node>q;
bool cmp1(node n1, node n2){
if(n1.a!=n2.a) return n1.a<n2.a;
return n1.id<n2.id;
}
ll ans[N];
int main(){
int n, k;
ll x;
scanf("%d%d%I64d", &n, &k, &x);
for(int i=0; i<n; i++) scanf("%I64d", &arr[i].a), arr[i].id=i;
sort(arr, arr+n, cmp1);
int kk=0;
for(kk=0; kk<n; kk++){
if(arr[kk].a>=0) break;
}
//有偶数个负数,尽可能的处理出奇数个负数
if(kk%2==0){
if(kk==0) {
while(k--) {
arr[0].a-=x;
if(arr[0].a<0) break;
}
}
else if(kk==n){
while(k--) {
arr[n-1].a+=x;
if(arr[n-1].a>=0) break;
}
}
else{
arr[kk-1].aa = abs(arr[kk-1].a);
arr[kk].aa = arr[kk].a;
if(arr[kk-1].aa<arr[kk].aa){
while(k--) {
arr[kk-1].a+=x;
if(arr[kk-1].a>=0) break;
}
}
else{
while(k--) {
arr[kk].a-=x;
if(arr[kk].a<0) break;
}
}
}
}
while(!q.empty()) q.pop();
for(int i=0; i<n; i++){
arr[i].aa = abs(arr[i].a);
q.push(arr[i]);
}
if(k>=0){
while(k--){
node s = q.top();q.pop();
s.aa+=x;
if(s.a<0) s.a = -s.aa;
else s.a = s.aa;
q.push(s);
}
}
while(!q.empty()) {
node s = q.top();q.pop();
ans[s.id] = s.a;
}
for(int i=0; i<n; i++){
if(i==n-1) printf("%I64d\n", ans[i]);
else printf("%I64d ", ans[i]);
}
return 0;
}