【题解】AtCoder ABC365

T1

链接:CH, JP

按题意模拟即可。

#include <bits/stdc++.h>
using namespace std;
int y;
int main(){
    scanf("%d", &y);
    if(y % 4 != 0)
        printf("365\n");
    else if(y % 4 == 0 && y % 100 != 0)
        printf("366\n");
    else if(y % 100 == 0 && y % 400 != 0)
        printf("365\n");
    else if(y % 400 == 0)
        printf("366\n");
    return 0;
}

T2

链接:CH, JP

pair 存储数据和它的编号,从小到大排序之后输出倒数第二个数据的编号。
pair 的默认排序方法是按照 first 从小到大排序)

#include <bits/stdc++.h>
using namespace std;
const int N = 105;
int n;
pair<int, int> arr[N];
int main(){
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
        scanf("%d", &arr[i].first), arr[i].second = i;
    sort(arr + 1, arr + 1 + n);
    printf("%d\n", arr[n - 1].second);
    return 0;
}

T3

链接:CH, JP

如果 x 的值很大,最后的总花费应为 a,所以如果有 am,输出 infinite,结束程序。
对于剩下的情况,可以发现,对于 x<x,若 x 的补贴限额能使总花费不超过 mx 也能做到;对于 x>x,若 x 会让总花费超过 mx 也会。所以,本题的答案具有单调性:在一定范围内x 越大,总花费越大,反之则越小。
考虑用二分答案求解。令左端点 l=0,右端点 r=2×1014+1(数据最大范围),对于一个 x,验证它是否能让总花费不超过 m。若可以,将左端点移到 x,若不可以,将右端点移到 x。最终 l+1=r 时,l 的值即为 x 的最大值。
注意:数据较大,要开 long long

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 2e5 + 5;
const ll inf = 2e14 + 1;
ll n, m, arr[N];
inline bool check(ll x){
    ll sum = 0;
    for(int i = 1; i <= n; i++)
        sum += min(x, arr[i]);
    return sum <= m;
}
int main(){
    scanf("%lld%lld", &n, &m);
    ll s = 0;
    for(int i = 1; i <= n; i++){
        scanf("%lld", &arr[i]);
        s += arr[i];
    }
    if(s <= m){
        printf("infinite\n");
        return 0;
    }
    ll l = 0, r = inf;
    while(l + 1 != r){
        ll mid = l + r >> 1;
        if(check(mid))
            l = mid;
        else
            r = mid;
    }
    printf("%lld\n", l);
    return 0;
}

T4

链接:CH, JP

fi,0 表示前 i 局高桥在不违反规则的情况下平局时,最多能胜多少场;
fi,1 表示前 i 局高桥在不违反规则的情况下获胜时,最多能胜多少场。
g(c)={'P'c='R''S'c='P''R'c='S'(即对方出 c 时高桥的对策)
有:

fi,0=max({fi1,0si1sifi1,1g(si1)si)

fi,1=max({fi1,0si1g(si)fi1,1g(si1)g(si))+1

注意初始化:f1,0=0,f1,1=1

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
int n, dp[N][2];
char s[N];
inline char get(char c){
    if(c == 'R')
        return 'P';
    else if(c == 'P')
        return 'S';
    else if(c == 'S')
        return 'R';
}
int main(){
    scanf("%d%s", &n, s + 1);
    dp[1][1] = 1, dp[1][0] = 0;
    for(int i = 2; i <= n; i++){
        char c1 = s[i - 1], c2 = get(s[i - 1]), c3 = s[i], c4 = get(s[i]);
        dp[i][0] = max((c1 != c3 ? dp[i - 1][0] : -1), (c2 != c3 ? dp[i - 1][1] : -1));
        // 由于 dp 数组中不会出现负数,所以取最大值时如果一个条件不成立,就会自动转成另一个值直接被赋值给 dp
        dp[i][1] = max((c1 != c4 ? dp[i - 1][0] : -1), (c2 != c4 ? dp[i - 1][1] : -1)) + 1;
    }
    printf("%d\n", max(dp[n][0], dp[n][1]));
    return 0;
}
posted @   Prülystic  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示