「Atcoder」abc242 题解

A - T-shirt

Code
void solve()
{
    int a, b, c, x;
    cin >> a >> b >> c >> x;
  
    if(x <= a) printf("%.12lf\n", 1.0);
    else if(x <= b)
    {
        double res=c;
        res /=  (b-a);
        printf("%.12lf\n",res);
    }
    else printf("%.12lf\n",0.0);
}

B - Minimize Ordering

Code
void solve()
{
    string s; cin >> s;
    sort(s.begin(), s.end());
    cout << s;
}

C - 1111gal password

Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;

ll n, dp[N][10];

int siz(ll n) {int len = 0;while (n){len++;n /= 10;}return len;}

int main()
{
    cin >> n;	int len = siz(n);
    for (int i = 1; i <= 9; i++)	dp[1][i] = 1;
        
    for (int i = 2; i <= n; i++)
        for (int j = 1; j <= 9; j++)
            if (j == 1)	dp[i][j] = (dp[i - 1][j] % mod + dp[i - 1][j + 1] % mod) % mod;
            else if (j == 9) dp[i][j] = (dp[i - 1][j] % mod + dp[i - 1][j - 1] % mod) % mod;
            else dp[i][j] = (dp[i - 1][j] % mod + dp[i - 1][j - 1] % mod + dp[i - 1][j + 1] % mod) % mod;
              
    ll res = 0;
    for (int i = 1; i <= 9; i++)	res = (res % mod + dp[n][i] % mod) % mod;
        
    cout << res;
    return 0;
}

D - ABC Transform(二叉树/递归)

题目描述

avatar

解题思路

思路请参考Hanasakiii的题解,这里只对令人疑惑的地方进行记录
问:为什么是%3?
avatar
由图可知变换总是ABC ABC这样循环的 所以是%3

Code
#include <bits/stdc++.h>
using namespace std;
string s;

long long solve(long long t, long long k)
{
    if (t == 0) return 1LL * (s[k] - 'A');  // 如果已经递归到底层了,直接返回
    if (k == 0) return 1LL * (s[0] - 'A' + t) % 3;  // 如果k = 0说明已经是访问到第一个字符了,只需再加上层数即可
    return (solve(t - 1, k / 2) + k % 2 + 1) % 3;
    /*上面k % 2 + 1 这个操作实则就是左右子树的判断,是左子树就+1,是右子树就+2 加上的数值其实就是“次数”
    举例:如ABC-> BCCAAB  BCCAAB中第二个C是B的左节点,因此在它的父节点基础上+1,这样才能从B变到C;
    如果要让B变到A必须要+2, 也即是让A成为B的右节点
    */
}

int main()
{
    cin >> s;
    int q;  cin >> q;
    
    while (q--) 
    {
        long long t, k; cin >> t >> k;
        cout << char('A' + solve(t, k - 1)) << '\n';
    }
    return 0;
}

E - (∀x∀)

题目描述

avatar

解题思路

思路请参考Hanasakiii的题解
对于一个字符串s,字典序小于s的数量决定于s的前一半字符(偶数为长度n / 2,奇数为(n + 1) / 2)
ABCD取决于AB, ABACD取决于ABA
所以可以将给定的字符串s分为两半来做
其中对于奇数长度的字符串,分为一半后,需要将left翻转后的字符right减去首元素
ABACD分为一半后,left = ABA, rihgt = (ABA的翻转 - 首元素) = BA。
最后需要一个特判,left + right <= s的话,需要再加1

Code
#include <bits/stdc++.h>
using namespace std;
const int mod = 998244353;

void solve()
{
    int n; cin >> n;
    string s; cin >> s;
    string t = s;
    string left = t.substr(0, (n + 1) / 2), right = left;  // 分为两半
    reverse(right.begin(), right.end());  // right为left的翻转,为最后的特判做铺垫

    if (n & 1)  right.erase(right.begin());  // 奇数长度的特殊处理
    int cnt = 0;
    for(auto ch : left) cnt = (cnt * 26 + ch - 'A') % mod;
    if (left + right <= s)  cnt = (cnt + 1) % mod;  // 最后的特判

    cout << cnt << '\n';
}

int main()
{
    int t;  cin >> t;
    while (t--) solve();
    return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wiz1code(算法号)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值