原题
题目大意
题目背景是讲有一组数据,然后你需要对这组数组进行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 }