第十届蓝桥杯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
 
我的代码:
 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 }

猜你喜欢

转载自www.cnblogs.com/savennist/p/12305556.html
今日推荐