AtCoder Beginner Contest 173 (Virtual)
A
签到题,直接向上取整再一减。
B
签到题,$map$记录一下就行。
D
题意
给你$n$个人,以任意顺序绕一圈,每次增加相邻两个中较小的值,第一个不算,问最大的结果是多少。
分析
一开始题目给的示例让我想偏了,我直接排序然后减了最小的,但其实可以在两边插入,所以实际用到的是前$\cfrac{n}{2}$个,具体是多少需要判断$n$的奇偶性。
1 #include<bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 const ll maxn=2e5+100;
5 const ll inf=0x3f3f3f3f3f3f3f3f;
6 ll t,n,m,a[maxn];
7 int main(){
8 //freopen("in.txt","r",stdin);
9 ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
10 cin>>t;
11 ll res=0;
12 for(int i=0;i<t;i++){
13 cin>>a[i];
14 }
15 sort(a,a+t,greater<int>());
16 res=a[0];
17 for(int i=1;i<=t/2-1;i++) res+=a[i]*2;
18 if(t&1) res+=a[t/2];
19 cout<<res<<endl;
20 return 0;
21 }
E
题意
给出一串数字,带正负,要求你选出$k$个数字,问最大乘积是多少。
分析
判断$k$的奇偶性,偶数时一定是选出所有俩俩乘积最大的,可以从两头扫,每次增加较大的乘积;当$k$为奇数时,先加入最大的正数,然后同上;如果没有正数的话再特殊判断一下。害呀,判断奇偶性的时候忘了变$k$的值了,WA了好几发,然后再交的时候又忘把答案变成正数。(还好只是模拟,不然我气死)
1 #include<bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 const ll maxn=2e5+100;
5 const ll inf=0x3f3f3f3f3f3f3f3f;
6 const ll mod=1e9+7;
7 ll t,n,k,a[maxn];
8 int main(){
9 freopen("in.txt","r",stdin);
10 ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
11 cin>>n>>k;
12 ll res=1,zheng=0,fu=0;
13 for(int i=0;i<n;i++){
14 cin>>a[i];
15 if(a[i]>0) zheng++;
16 }
17 sort(a,a+n);
18 if(zheng==0){
19 if(k%2==1){
20 for(int i=1;i<=k;i++){
21 res=res*a[n-i]%mod;
22 }
23 }else{
24 for(int i=0;i<k;i++){
25 res=res*a[i]%mod;
26 }
27 }
28 cout<<(res+mod)%mod<<endl;
29 return 0;
30 }
31 if(k%2==0){
32 zheng=n-1,fu=0;
33 }else{
34 zheng=n-2,fu=0,k-=2;//打的时候这里忘了减2了
35 res=a[n-1];
36 }
37 for(;k>0&&zheng-1>=0&&fu+1<n;k-=2){
38 if(a[zheng]*a[zheng-1]<a[fu]*a[fu+1]){
39 res=res*a[fu]%mod*a[fu+1]%mod;
40 fu+=2;
41 }else{
42 res=res*a[zheng]%mod*a[zheng-1]%mod;
43 zheng-=2;
44 }
45 }
46 while(res<0){
47 res+=mod;
48 }
49 cout<<res<<endl;
50 return 0;
51 }