由于作者代码风格有变,头文件较长,以下代码均舍去头文件。

abc257_a

题目翻译

给定一个 $n$,生成一个字符串,内容为 $n$ 个 $\tt{A}$,$n$ 个 $\tt{B}$,一直到 $n$ 个 $\tt{Z}$。

输出第 $k$ 位。

题目思路

直接模拟到第 $n$ 位。

这是最暴力的写法。

也可以用数学知识算一下当前是哪个字符。

我采用了最暴力的。

AC 代码

int main()
{
    int n, x, cnt = 0;
    cin >> n >> x;
    for (int i = 1; i <= 26; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            cnt++;
            if (cnt == x)
            {
                cout << char (i + 'A' - 1) << endl;
                return 0;
            }
        }
    }
    return 0;
}

abc257_b

题目翻译

有个长度为 $n$ 的道路,第 $a_i$ 个位置上有一个士兵。

有 $Q$ 次操作,第 $i$ 次操作将第 $l_i$ 个士兵往右一位。

如果自己是最后一个位置或者右边有人,不移动。

输出士兵位置。

题目思路

模拟。

由于 $n\leq100,Q \leq1000$,每次扫一遍不超时。

AC 代码

int a[205];
int main()
{
    int n, k, q;
    cin >> n >> k >> q;
    for (int i = 1; i <= k; i++)
    {
        int x;
        cin >> x;
        a[x] = 1;
    }
    for (int i = 1; i <= q; i++)
    {
        int l, cnt = 0;
        cin >> l;
        for (int j = 1; j <= n; j++)
        {
            if (a[j] == 1)
            {
                cnt++;
            }
            if (cnt == l)
            {
                if (j + 1 <= n && a[j + 1] != 1)
                {
                    a[j] = 0;
                    a[j + 1] = 1;
                }
            }
        }
    }
    for (int i = 1; i <= n; i++)
    {
        if (a[i] == 1)
        {
            cout << i << " ";
        }
    }
    return 0;
}

abc257_c

题目翻译

有 $n$ 个人,每个人有个体重 $w_i$,以及 $\tt{0}$ 代表他是小孩,$\tt{1}$ 代表成人。

我们认为,比 $X$ 轻的是小孩,反之是成人。

请选择一个 $X$,使身份匹配正确的人数最多。

题目思路

把这些人按体重排序,相同体重成人在前。

统计这里一共多少成人。

对于每个 $[1,i]$ 的区间,算一下类似前缀和的操作。

是小孩,之前统计的加 $1$,反之 $-1$。

AC 代码

struct node
{
    bool f;
    int w;
} a[200005];
bool cmp (node x, node y)
{
    if (x.w == y.w)
    {
        return x.f > y.f;
    }
    return x.w < y.w;
}
int main()
{
    int n, ch = 0, ans;
    cin >> n;
    char c;
    for (int i = 1; i <= n; i++)
    {
        cin >> c;
        if (c == '0')
        {
            a[i].f = 0;
        }
        else
        {
            a[i].f = 1;
            ch++;
        }
    }
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i].w;
    }
    sort (a + 1, a + n + 1, cmp);
    ans = ch;
    for (int i = 1; i <= n; i++)
    {
        if (a[i].f == 0)
        {
            ch++;
        }
        else
        {
            ch--;
        }
        ans = max (ans, ch);
    }
    cout << ans << endl;
    return 0;
}

abc257_d

题目翻译

有 $n$ 个蹦床,每个蹦床坐标为 $(x_i,y_i)$,并拥有主场 buff $p_i$ 加持。

(这样说是不是通俗易懂

可以自选起点。

如果从第 $i$ 个往第 $j$ 个跳,所需 $S\times p_i\geq \left|x_i-x_j\right|+\left|y_i-y_j\right|$ 的必备条件。

问 $S$ 最小多少。

题目思路

Floyd 最短路。

先求出从 $i$ 跳到 $j$ 的所需 $S$,再用 Floyd 做最短路,看经过中间过渡,能否缩小 $S$。

转移即为 $f_{i,j} = \min(\max (f_{i,k}, f_{k,j}), f{i,j})$。

AC 代码

ll x[205], y[205], p[205];
ll f[205][205];
int main()
{
    ll n;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> x[i] >> y[i] >> p[i];
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            ll s = abs (x[i] - x[j]) + abs (y[i] - y[j]);
            if(s%p[i]==0)f[i][j]=s/p[i];
            else f[i][j]=s/p[i]+1;
        }
    }
    for (int k = 1; k <= n; k++)
    {
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= n; j++)
            {
                f[i][j] = min (max (f[i][k], f[k][j]), f[i][j]);
            }
        }
    }
    ll ans = 1e20;
    for (int i = 1; i <= n; i++)
    {
        ll x = -1e20;
        for (int j = 1; j <= n; j++)
        {
            x = max (f[i][j], x);
        }
        ans = min (ans, x);
    }
    cout << ans << endl;
    return 0;
}

abc257_e

题目翻译

有 $9$ 种数字,$1,2,\dots9$。

数字 $i$ 可以花 $c_i$ 的价格购买,你有 $n$ 元。

最后输出你购买的数字拼成的最大值。

题目思路

我们考虑,先让位数最大。

然后,再最大化最高位、次高位、次次高位,一直往下。

最大位数,即为用 $n$ 除以最便宜的价钱。

然后,你可能会有剩余的钱。

剩余的,我们开始置换。

从 $9$ 开始枚举,能换就换,并输出你置换的数字。

这样最大化了较高位,还保证位数没有变少。

具体可以品味下代码。

AC 代码

int c[20];
int main()
{
    int n, mnc = INT_MAX, maxn;
    cin >> n;
    for (int i = 1; i <= 9; i++)
    {
        cin >> c[i];
        if (c[i] <= mnc)
        {
            mnc = c[i];
            maxn = i;
        }
    }
    int cnt = n / mnc;
    int x = 0, cnt2 = 0;
    int s = n - cnt * mnc;
    for (int i = 9; i >= 1; i--)
    {
        if (i > maxn)
        {
            if (c[i] - mnc <= s)
            {
                cnt2 = s / (c[i] - mnc);
                cnt -= cnt2;
                s%=c[i] - mnc;
                for (int j = 1; j <= cnt2; j++)
                {
                    cout << i;
                }
            }
        }
    }
    for (int i = 1; i <= cnt; i++)
    {
        cout << maxn;
    }
    return 0;
}
最后修改:2023 年 04 月 20 日
v我50吃疯狂星期四