AtCoder Beginner Contest 365 A~D 题

网址链接:Toyota Programming Contest 2024#8(AtCoder Beginner Contest 365) - AtCoder

A题:

A - Leap Year (atcoder.jp)

题目很简单就是判断是否是闰年,然后根据是否是闰年来给出所给年份的天数,如果是润年那么是366天,如果不是闰年那么就是365天


代码实现:

#include<bits/stdc++.h>

using namespace std;

int main()
{
    int n;
    cin>>n;
    if(n%400==0 || (n%4==0 && n%100!=0)) cout<<"366"<<endl;
    else cout<<"365"<<endl;
    return 0;
}

B题: 

B - Second Best (atcoder.jp)
 

输出第二大的值的下标,使用结构体,进行排序后输出第二大的下标即可


代码实现:

#include<bits/stdc++.h>

using namespace std;

const int N=105;

struct node
{
    int val;
    int index;
}a[N];

bool cmp(node x, node y)
{
    return x.val>y.val;
}

int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i].val;
        a[i].index=i;
    }
    sort(a+1,a+1+n,cmp);
    cout<<a[2].index<<endl;
    return 0;
}

C题:

C - Transportation Expenses (atcoder.jp)

问题陈述

有 N 人参加一项活动, i /人的交通费用是 Ai​ 日元。

活动组织者高桥(Takahashi)决定设定交通补贴的最高限额为 x 。 i 人的补贴为 min⁡(x,Ai)日元。这里, x 必须是一个非负整数。

高桥的预算为 M 日元,他希望所有 N 人的交通补贴总额最多为 M 日元,那么补贴限额 x 的最大可能值是多少?

如果补贴限额可以无限大,请报告。

Constraints

  • 1≤N≤2×105
  • 1≤M≤2×10^14
  • 1≤Ai≤109
  • All input values are integers.

思路:
 

x的取值范围是从0到1 1e9 , 如果x 大于1e9 的话,所有的min(A[i],x) 都是A[i] ,因为题干中A[i] 的取值范围小于等于 1e9 , 这道题我们使用二分答案,l =0; r= 1e9 , 然后看看mid 满不满足条件, 如果满足条件的话,我们就让l= mid .如果不满足条件的话, 我们就缩小范围,r=mid-1 。
为什么呢,如果说mid 已经满足条件了,那么我们就需要看看比mid大的数中有没有可以满足条件的,因为题干要就使补贴限额x 的最大尽可能的大,如果mid不满足条件,我们就让r= mid-1;


代码实现:

#include<bits/stdc++.h>

using namespace std;

const int N=200010;

int n;

long long M;

int A[N];

bool check(int x)
{
    long long sum=0;
    for(int i=1;i<=n;i++)
    {
        sum+=min(A[i],x);
        if(sum>M) return false;
    }
    return true;
}

int main()
{
    cin>>n>>M;
    for(int i=1;i<=n;i++) cin>>A[i];
    int l=0; int r=1e9;
    while(l<r)
    {
        int mid=l+(r-l+1)/2;
        if(check(mid)) l=mid;
        else r=mid-1;
    }
    if(l==1e9) cout<<"infinite"<<endl;
    else cout<<l<<endl;
    return 0;
}


D题:

D - AtCoder Janken 3

问题陈述

高桥和青木玩了 N 次石头剪刀布。[注:在这个游戏中,石头赢剪刀,剪刀赢纸,纸赢石头。

青木的动作由长度为 N 的字符串 S 表示,字符串由 "R"、"P "和 "S "组成。 i /th字符 S 表示青木在 i /th对局中的棋步:R "表示 "石头","P "表示 "纸","S "表示 "剪刀"。

高桥的棋步满足以下条件:

  • 高桥从未输给过青木。
  • 对于 i=1,2,…,N−1 ,高桥在 i /th对局中的棋步与他在 (i+1) /th对局中的棋步不同。

请确定高桥的最大胜局数。

可以保证存在一个满足这些条件的高桥下棋顺序。

Constraints

  • 1≤N≤2×105
  • S is a string of length N consisting of RP, and S.
  • N is an integer.

思路讲解:

D题的话,在比赛当中我没有做出来,我是用贪心做的,就是再如果有可能赢的情况下就让他赢,因为题干已经说了,他不可能输,因此,他每局只有赢或者是平两种情况,我就让他如果这句可以赢的那种抉择如果上一局没有使用的话,就让其在这一局中使用,让他赢,否则就平,这种策略的话,只考虑了眼前的一步,因为你的决策可能会对后续的出法产生影响,因此要使用动态规划,来求取最优解。

dp[i][j] 表示 经历 i 次 出手, 第 i 次 我出 j 所能赢得的最大胜利场数 

可以让 0 代表 S, 1 代表 R, 2 代表 P 具体看代码吧

代码实现:

#include<bits/stdc++.h>

using namespace std;

const int N=200010;

int dp[N][3];

int main()
{
    int n;
    cin>>n;
    string S;
    cin>>S;
    S=' '+S;
    /// 0->S
    /// 1->R
    /// 2->P
    for(int i=1;i<=n;i++)
    {
        if(S[i]=='S')
        {
            dp[i][1]=max(dp[i-1][0],dp[i-1][2])+1; // 因为对手出的是剪刀,我们不能输,只能出石头1 赢
            dp[i][0]=max(dp[i-1][1],dp[i-1][2]);//或者剪刀0 平 又要和上局不一样 这一局是1, 则上一局只能是0 或者是 2
        }
        else if(S[i]=='R')
        {
            dp[i][2]=max(dp[i-1][0],dp[i-1][1])+1;
            dp[i][1]=max(dp[i-1][0],dp[i-1][2]);
        }
        else
        {
            dp[i][0]=max(dp[i-1][1],dp[i-1][2])+1;
            dp[i][2]=max(dp[i-1][0],dp[i-1][1]);
        }
    }
    cout<<max({dp[n][0],dp[n][1],dp[n][2]})<<endl;
    return 0;
}


 

  • 13
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值