『MdOI R2』Car

GitHub跳转原题关系图返回列表

先判断是不是 `MDA` 本地车;若是,就从右往左找第一个数字作为尾号,再按星期对应的尾号规则输出 5 天限行情况。

OJ: luogu

题目 ID: P6382

难度:入门

标签:模拟字符串

日期: 2026-06-19 09:53

题意

给出一个车牌号。

需要判断这辆车在周一到周五是否限行,并按顺序输出 5 个 0/1

规则是:

  • 如果前三位不是 MDA,说明是外地车,周一到周五都限行;
  • 如果是本地车,就看车牌尾号,也就是从右往左第一个数字;
  • 周一到周五分别限行的尾号是:
    • 周一:19
    • 周二:28
    • 周三:37
    • 周四:46
    • 周五:50

思路

这题就是直接按规则模拟。

最直接的版本如下:

cpp
// brute.cpp:按题意逐条判断本地车、外地车和尾号限行规则。
#include <bits/stdc++.h>
using namespace std;

string s;

int get_tail_digit() {
    for (int i = (int) s.size() - 1; i >= 0; i--) {
        if (s[i] >= '0' && s[i] <= '9') {
            return s[i] - '0';
        }
    }
    return -1;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> s;

    if (s.substr(0, 3) != "MDA") {
        cout << "1 1 1 1 1\n";
        return 0;
    }

    int tail = get_tail_digit();
    int ans[5] = {0, 0, 0, 0, 0};

    if (tail == 1 || tail == 9) ans[0] = 1;
    if (tail == 2 || tail == 8) ans[1] = 1;
    if (tail == 3 || tail == 7) ans[2] = 1;
    if (tail == 4 || tail == 6) ans[3] = 1;
    if (tail == 5 || tail == 0) ans[4] = 1;

    for (int i = 0; i < 5; i++) {
        if (i) cout << ' ';
        cout << ans[i];
    }
    cout << '\n';

    return 0;
}

先判断本地车还是外地车

前三位如果不是 MDA,那就直接输出:

1 1 1 1 1

因为外地车工作日都限行,不需要再看尾号。

本地车怎样找尾号

题目已经定义了尾号:

从右往左找到的第一个数字。

所以直接从字符串末尾往前扫,第一个数字字符就是尾号。

怎样输出 5 天结果

得到尾号后,只要分别判断它是否落在每一天对应的两个数字里即可。

比如尾号是 6,那只有周四限行,答案就是:

0 0 0 1 0

代码

cpp
#include <bits/stdc++.h>
using namespace std;

string s;
int ans[5];

int get_tail_digit() {
    for (int i = (int) s.size() - 1; i >= 0; i--) {
        if (s[i] >= '0' && s[i] <= '9') {
            return s[i] - '0';
        }
    }
    return -1;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> s;

    if (s.substr(0, 3) != "MDA") {
        cout << "1 1 1 1 1\n";
        return 0;
    }

    memset(ans, 0, sizeof(ans));
    int tail = get_tail_digit();

    if (tail == 1 || tail == 9) {
        ans[0] = 1;
    }
    if (tail == 2 || tail == 8) {
        ans[1] = 1;
    }
    if (tail == 3 || tail == 7) {
        ans[2] = 1;
    }
    if (tail == 4 || tail == 6) {
        ans[3] = 1;
    }
    if (tail == 5 || tail == 0) {
        ans[4] = 1;
    }

    for (int i = 0; i < 5; i++) {
        if (i > 0) {
            cout << ' ';
        }
        cout << ans[i];
    }
    cout << '\n';

    return 0;
}

复杂度

  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(1)O(1)

这里 n 就是车牌长度,实际上非常小。

总结

这题没有隐藏算法,关键只是把题意里的三条规则老老实实翻译成代码:

  1. 判断本地/外地;
  2. 从右往左找尾号;
  3. 按星期映射输出结果。