第十届蓝桥杯CB题目I-分析
思路分析://感谢写文博主
思路:相信大多数人和我一样在比赛的时候把这题想的太简单了_(:з」∠)_ 这题和去年的最后一题很类似,就是分类讨论,去年放在了最后一题,今年在倒数第二题,说明难度不算太难,分析出来了就会觉得emmm好坑……那么下面开始分析,我是按照符号的个数和负数的个数来分类讨论的:
①负号个数为0,那么没有办法只能全加
②负号个数等于负数个数,那么减去所有负数就能得到最大结果
③负号个数小于负数个数,可以通过加号的补充来达到上一种情况的效果的
比如(6 5 -4 -3 -2 -1),有1个减号,那么可以变成 6 + 5 - ( -4 + -3 + -2 + -1 ) ;有2个减号,那么可以变成 6 + 5 - -4 - ( -3 + -2 + -1 ) ;有3个减号,那么可以变成6 + 5 - -4 - -3 - ( -2 + -1 )
④负号个数大于负数个数,那么先把负数都减掉,然后再减较小的正数
综上所述,第一种是直接求和,第二种和第三种是可以合并的,即求绝对值和,第四种是先求和再减去多余负号个数的小正数。
————————————————
版权声明:本文为CSDN博主「ryo_218」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ryo_218/article/details/89515960
————————————————
版权声明:本文为CSDN博主「ryo_218」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ryo_218/article/details/89515960
我的代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<string> 5 #include<algorithm> 6 using namespace std; 7 int n,lenth; 8 int m;//减号个数 9 int minus_num;//负数的个数 10 const int maxn = 200005; 11 int aim[maxn]; 12 13 int solve() 14 { 15 int ans=0; 16 if(m==0) 17 { 18 for(int i=0;i<lenth;i++) 19 ans+=aim[i]; 20 return ans; 21 } 22 if(m<=minus_num) 23 { 24 for(int i=0;i<minus_num;i++) 25 { 26 ans+=aim[i]; 27 } 28 ans=-ans; 29 for(int i=minus_num;i<lenth;i++) 30 { 31 ans+=aim[i]; 32 } 33 return ans; 34 } 35 if(m>minus_num) 36 { 37 for(int i=0;i<minus_num;i++) 38 { 39 ans+=aim[i]; 40 } 41 ans=-ans; 42 for(int i=minus_num;i<m;i++) 43 { 44 ans+=(-aim[i]); 45 } 46 for(int i=m;i<lenth;i++) 47 { 48 ans+=aim[i]; 49 } 50 return ans; 51 } 52 return 0; 53 } 54 55 int main() 56 { 57 memset(aim,0,sizeof(aim)); 58 cin>>n>>m; 59 lenth=n+m+1; 60 for(int i=0;i<lenth;i++) 61 { 62 int a;cin>>a; 63 if(a<0)minus_num++; 64 aim[i]=a; 65 } 66 sort(aim,aim+lenth); 67 printf("%d\n",solve()); 68 return 0; 69 }
转载的博主的代码:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<string> 8 #include<vector> 9 #include<queue> 10 #include<map> 11 #include<set> 12 using namespace std; 13 long long pos[100000]={0}; 14 long long neg[100000]={0}; 15 16 int main() 17 { 18 int n,m,p=0,q=0; 19 cin>>n>>m; 20 long long ans=0; 21 for(int i=0;i<n+m+1;i++) 22 { 23 long long num; 24 cin>>num; 25 ans+=num; 26 if(num>0)//记录正数 27 pos[p++]=num; 28 else//记录非正数 29 neg[q++]=num; 30 } 31 if(m==0)//负号个数为0 32 cout<<ans<<endl; 33 else if(m<q)//负号个数小于负数个数 34 { 35 for(int i=0;i<q;i++) 36 ans-=neg[i]*2;//第一遍相当于减掉了一次负数绝对值,第二遍时要补2倍 37 cout<<ans<<endl; 38 } 39 else//负号个数大于负数个数 40 { 41 for(int i=0;i<q;i++) 42 ans-=neg[i]*2; 43 sort(pos,pos+p); 44 for(int i=0;i<m-q;i++) 45 ans-=pos[i]*2;//第一遍已经加了一次正数,去掉时要减2倍 46 cout<<ans<<endl; 47 } 48 return 0; 49 }