(2024年2月洛谷大更新,取消了个人博客功能,将博客转为推文,遂决定自行搭建Blog,并将文章迁移至此 (其实就只有两篇2333)

其实在很久之前就想搞一个自己的blog了,每次浏览大佬的blog都会被大佬们自己搭建的世界所触动,现如今 $Messywind$ 学长给我们的每人创建一个blog养成写发电小作文的建议也算是促成这个blog的契机。

顺便进行第一篇题解的写:

啥都不会的人写的题解真的可以看嘛2333

题目 受害者 来自于AtCoder Beginner Contest 336 的 $C$ 题。C - Even Digits

题目大意是:当一个数的各位都是偶数时,称作这个数为好数 $(good\ integer)$,需要我们求第 $N$ 小的 $good\ integer$ 。

当看到这道题的时候,第一个想法是暴力枚举,声明一个 $count$ 变量,从 $0$ 开始枚举,如果符合条件则 $count$++,当 $count==N$ 时,则是所求的答案。
但是当我看了一眼数据范围……

$1≤N≤10^{12}$

$1≤N≤10^{12}$

$1≤N≤10^{12}$

emmm……虽然时间限制给到了 $2s$ ,但是还是会超时,所以选择更优的算法比较好。

首先让我们先枚举一下题干所定义的 $good\ integer$ :

$0\ 2\ 4\ 6\ 8$
$20\ 22\ 24\ 26\ 28$
$40\ 42\ 44\ 46\ 48$
$60\ ………$
$80\ ………$
$200\ ………$
$220\ …………$

其实规律就已经很明显了,我们可以发现这些数字每 $5$ 个进位一次,也就是说,这些 $good integer$ 本质上是一组步长为 $2$ 的五进制数,那么很显而易见地,我们可以将 $N$ 转化为五进制数,输出转化后的第 $N$ 个数即为我们所需要求的答案。
需要注意的是,因为第一个数是 $0$ ,所以我们实际求得结果时要将 $N$ 减去一再乘步长即 $answer = (N-1)×2$ ,此时的 $N$ 是转化为五进制数之后的。
因为牵扯到进位转换操作,所以转化为五进制之后的 $N$ 在做减法时并不能直接减一,所以要使用类似于高精度减法的思想来将其放在数组中进行操作。即:

if (!vec[0])
{
    int brw = 1;
    for (int i = 0; i < len; i++)
    {
        vec[i] -= brw;
        brw = 0;
        if (vec[i] < 0)
        {
            vec[i] += 5;
            brw = 1;
        }
    }
}

只有当个位数字为 $0$ 时我们才需要退位操作,所以在操作之前需要判断一下个位是否为 $0$ 来判断是否有必要进行退位。
随后逆序输出即为答案。
完整 $AC$ 代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<queue>
#include<stack>
#include<string>
using namespace std;
#define int long long
#define endl '\n'
int n, m, a, t, b, k, y, h;
const int MAXN = 1e6 + 10;
const int MOD = 998244353;
int arr[MAXN];
signed main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    vector<int>vec;
    while (n)
    {
        vec.push_back(n % 5);
        n /= 5;
    }
    int len = vec.size();
    if (!vec[0])
    {
        int brw = 1;
        for (int i = 0; i < len; i++)
        {
            vec[i] -= brw;
            brw = 0;
            if (vec[i] < 0)
            {
                vec[i] += 5;
                brw = 1;
            }
        }
    }
    else
        vec[0]--;
    for (int i = len - 1; i >= 0; i--)
        cout << vec[i]*2;
}

有人提交时忘记删除测试用的输出代码导致WA了一发我不说是谁(悲

大胆提交,压力留给队友.jpg

至此,蒟蒻的第一篇blog&&第一篇题解就结束啦!