Codeforces Round #574 (Div. 2)部分题解(A~C)


前言

要开始想办法逃离挂科的困境了。

在这里插入图片描述


A - Drinks Choosing (思维+水题)

比赛链接:https://codeforces.com/problemset/problem/1195/A

题目大意

现在你要帮 n n n位同学买饮料。

请添加图片描述
饮料店现在有 k k k种饮料,第 i i i个同学想要喝第 a i a_i ai( 1 < = a i < = k 1<=a_i<=k 1<=ai<=k)种饮料。
现在饮料店有活动,同一种饮料买 m m m( m > 0 m>0 m>0并且 m m m为偶数)瓶则可以享受免单。

你本着能不花钱就不花钱,但也不能铺张浪费的原则来购物,也就是说:

如果 n n n为奇数,你可以多买 1 1 1瓶(即 n + 1 n+1 n+1瓶)。
如果 n n n为偶数,你只能买 n n n瓶。

现在问,最多有多少位同学可以免费喝到自己心仪的饮料。

思路

简单的思维题。

算出一定可以喝到心仪饮料的人数 a n s ans ans,再算出不一定能喝到心仪饮料的人数 s u m sum sum

如果 s u m sum sum为奇数,那么在这之中就会有 ( s u m / 2 ) + 1 (sum/2)+1 (sum/2)+1个人可以喝到心仪饮料。
如果 s u m sum sum为偶数,就会有 ( s u m / 2 ) (sum/2) (sum/2)个人可以喝到心仪饮料。

AC代码

#include<iostream>
#include<random>
#include<bits/stdc++.h>
using namespace std;

const long long mod=1e9+7;
const int maxn=2e5+100;

int main()
{
    
    
    int n,k;
    map<int,int> mp;
    cin>>n>>k;
    for(int i=0;i<n;i++){
    
    
        int x;
        cin>>x;
        mp[x]++;
    }
    int ans=0;
    int sum=0;
    for(auto it:mp){
    
    
        //cout<<it.first<<" "<<it.second<<endl;
        ans+=(it.second/2)*2;
        if(it.second&1) sum++;
    }
    //cout<<ans<<endl;
    sum++;
    cout<<ans+sum/2<<endl;
    return 0;
}

B - Sport Mafia (暴力+水题)

比赛链接:https://codeforces.com/problemset/problem/1195/B

题目大意

Alya有一个盒子,一开始盒子里没有糖。

Alya每次都可以选择两种操作:
1. 1. 1.从盒子里拿一颗糖吃掉。这个操作只有在盒子里有糖的时候才会执行。
2. 2. 2.往盒子里放 x x x颗糖。每一次放糖都会比上一次多放一颗,第一次会放 1 1 1颗糖。

现在我们知道Alya操作了 n n n次,最后盒子里还有 k k k颗糖。
请问,Alya吃了多少颗糖?

思路

暴力跑 O ( n ) O(n) O(n)就可以。
记得开 l o n g long long l o n g long long,否则会爆数据的。

AC代码

#include<iostream>
#include<random>
#include<bits/stdc++.h>
using namespace std;

const long long mod=1e9+7;
const int maxn=2e5+100;

int main()
{
    
    
    long long n,k;
    cin>>n>>k;
    long long sum=n*(n+1)/2;
    int cnt=0;
    for(long long i=n;i>=0;i--){
    
    
        if(sum==k) break;
        sum-=i;
        cnt++;
        sum--;
    }
    cout<<cnt<<endl;
    return 0;
}

C - Basketball Exercise(动态规划)

比赛链接:https://codeforces.com/problemset/problem/1195/C

题目大意

现在操场上站着两排人,每一排有 n n n个,每个人的身高已给出。
你现在需要在这 2 ∗ n 2*n 2n个人之中选一些人组成一个篮球队。

你从第一列开始选人。
i ( i > = 2 ) i(i>=2) i(i>=2)个被选中的同学所在的列数要比第 i − 1 i-1 i1个被选中的同学所在的列数要大,并且两者不能相邻(即两个人在同一排)。

求最后整个篮球队所有人的总身高最大可以是多少?

思路

入门级别的动态规划问题。
连博主这种dp白痴的货色都知道,做动态规划最重要的,就是找到状态转移方程

根据题目描述,当我们考虑第一排的第i个同学时,此时篮球队的总身高的最优解应该为:

dp[1][i]=max(a[1][i]+dp[2][i-1],dp[1][i-1]);

其中 d p [ i ] [ j ] dp[i][j] dp[i][j]代表考虑第 i i i排第 j j j个同学后可以产生的最高总身高的值, a [ i ] [ j ] a[i][j] a[i][j]代表第 i i i排第 j j j个同学的身高。

第二排也是一样的:

dp[2][i]=max(a[2][i]+dp[1][i-1],dp[2][i-1]);

最后取 d p [ 1 ] [ n ] dp[1][n] dp[1][n] d p [ 2 ] [ n ] dp[2][n] dp[2][n]之中的最大值。

AC代码

///long long数据(会在第五个测试点卡住)
#include<iostream>
#include<random>
#include<bits/stdc++.h>
using namespace std;

const long long mod=1e9+7;
const int maxn=1e5+100;

int a[5][maxn];
long long dp[5][maxn];

int main()
{
    
    
    int n;
    cin>>n;
    for(int i=1;i<=2;i++)
        for(int j=1;j<=n;j++)
        cin>>a[i][j];
    dp[1][0]=0;
    dp[2][0]=0;
    for(int i=1;i<=n;i++){
    
    
        dp[1][i]=max(a[1][i]+dp[2][i-1],dp[1][i-1]);
        dp[2][i]=max(a[2][i]+dp[1][i-1],dp[2][i-1]);
    }
    cout<<max(dp[1][n],dp[2][n])<<endl;
}

感谢阅读,希望能对你产生一点用处。
(第7季二丫终于要回家了,wow~ ⊙o⊙)

在这里插入图片描述

"There is only one God and his name is Death."
"And there is only one thing we say to Death:"
"Not today."

吾日三省吾身:日更否?刷题否?快乐否?
更新了,但不是日更;已刷;happy!
吾心满意足。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_45750296/article/details/120772137
今日推荐