2019 GUDT WPTC 3 Div.2 Problem H(题解)

原题

题目大意

题目背景是讲有一组数据,然后你需要对这组数组进行k次操作,操作是指让这组数据的任何一个数乘以-1(可以对重复的数进行操作),问k此操作后,这组数据的和最大是多少.

题目分析

这道题的思路是,先对这组数据中原本就是负数的数进行操作,如果这个过程中k次操作用完了,那么直接输出操作后的数据之和.如果这个过程结束后k还有剩余,则剩余的数都将是正整数,那么将剩余的操作直接用在这组数据最小的那个数上(包括0),之后再输出这组数据之和即可.

代码

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <algorithm>
 6 #include <vector>
 7 #include <string>
 8 #include <utility>
 9 #include <queue>
10 #include <stack>
11 const int INF=0x3f3f3f3f;
12 using namespace std;
13 
14 typedef pair<int,int> P; //pair的first值表示数的绝对值,second值0表示数据是正的,1表示数据是负的
15 P a[100000];
16 
17 int main()
18 {
19     int n,k,s=0;
20     cin>>n>>k;
21     long long sum=0;
22     for(int i=0;i<n;i++)
23     {
24     cin>>a[i].first,sum+=a[i].first; //输入时顺便先算好原数据之和
25     if(!a[i].first) s=1;  //这里对0的数进行特殊化处理,其实处理不处理都无所谓
26     if(a[i].first<0) a[i].first*=-1,a[i].second=1; //如果是负数取绝对值并标记second
27     }
28     sort(a,a+n); //把数据按绝对值排序
29     while(k)
30     {
31         for(int i=n-1;i>=0&&k;i--) //从绝对值最大的开始扫负数
32         if(a[i].second)
33         {
34             a[i].second=0,sum=sum+2*a[i].first,k--;
35         }
36         if(s) break; //如果最小值是0,对0进行操作是无效的所以可以直接结束
37         while(k)//这里是把剩余的操作全都用在最小值上
38         {
39             if(a[0].second) a[0].second=0,sum=sum+2*a[0].first,k--;
40             else a[0].second=1,sum=sum-2*a[0].first,k--;
41         }
42 
43     }
44     cout<<sum<<endl;
45     return 0;
46 }

猜你喜欢

转载自www.cnblogs.com/VBEL/p/10404732.html
今日推荐