A-Thorns and Coins

题意

长度为的单元格路径,每个单元格有空、有金币、荆棘三种可能,人物从最左边开始向右移动,每次步长不多于2格,求能获得的最多金币数。

数据范围

.代表空,*代表荆棘,@代表金币

思路

从左往右,寻找第一个含有2个以上**连通块,其前的金币都可以达到。

参考代码

void solve() {
    int n;cin >> n;
    string s;cin >> s;
    int cnt = 0;
    bool f = true;
    for (int i = 0;i < n;i++) {
        if (s[i] == '@')cnt++;
        if (i > 0 && s[i] == '*' && s[i - 1] == '*'){
            break;
        }
    }
    cout << cnt << '\n';
}

B-Chaya Calendar

题意

查亚部落相信世界末日有个征兆,第个征兆每隔年出现一次,当观测到第个征兆后才会等待第个征兆。给出每个征兆的出现间隔,询问观测到所有个征兆所需要的年数。

ps:当第个征兆在第年被观测,部落会从第年开始等待第个征兆。

数据范围

思路

个征兆间隔年出现,若上一个征兆在第年被观测,则下一个征兆将在第年出现()。等待的时间是,也就是年。

参考代码

void solve() {
    int n;cin >> n;
    vector<ll>a(n);
    ll sum = 0;
    for (int i = 0;i < n;i++) {
        cin >> a[i];
        ll lf = a[i] - sum % a[i];
        sum += lf;
    }
    cout << sum << '\n';
}

C-LR-remainders

题意

有一个数组,一个正整数和长度为的命令(由LR组成的字符串),每次求数组中剩余数的积模的余数并输出,然后按照命令删数(L删去最左边的数,R删去最右边的数)。

数据范围

思路

反过来考虑,从最后一个删去的数开始,每次对积乘上上一次被删去的数,记录模m的值,逆序输出。

参考代码

void solve() {
    int n, m;cin >> n >> m;
    vector<int>a(n);
    for (int i = 0;i < n;i++) { cin >> a[i]; }
    string s;cin >> s;
    vector<int>b;
    int l = 0, r = n - 1;
    for (int i = 0;i < n;i++) {
        if (s[i] == 'L')b.push_back(a[l++]);
        else b.push_back(a[r--]);
    }
    ll ans = 1;
    vector<int>res;
    reverse(b.begin(), b.end());
    for (int i = 0;i < n;i++) {
        ans *= b[i];
        res.push_back(ans % m);
        ans %= m;
    }
    reverse(res.begin(), res.end());
    for (int i = 0;i < n;i++) {
        cout << res[i] << " ";
    }cout << '\n';
}

D-Card Game

题意

纸牌比大小游戏,有四种花色CDHS,同一种花色之间比较数字,数字大的胜出。同时,每局有一个王牌花色,该花色的牌可以比剩余三种花色的牌都大,王牌花色和王牌花色之间比较数字大小。

给出所有已经打出的牌,尝试复现对局情况(第二位玩家击败第一位玩家);如果不能复现,输出IMPOSSIBLE

数据范围

思路

模拟。

先对不同花色的牌分类,然后遍历同花色的牌,排序后,将非王牌花色放入一个序列,王牌花色单独一个序列。

从非王牌花色序列开始遍历,如果当前牌和其后一牌是同一种花色,凑成一对局;如果不是,用一张王牌花色和它凑成一个对局。假如可以凑成所有的对局,输出这些对局,否则不能构成对局。

参考代码

void solve() {
    int n;cin >> n;
    string w;cin >> w;
 
    int f = 0;
    switch (w[0]) {
    case 'S':f = 3;break;
    case 'H':f = 2;break;
    case 'D':f = 1;break;
    case 'C':f = 0;break;
    default:break;
    }
 
    vector<vector<string>>sp(4);
    for (int i = 0;i < 2 * n;i++) {
        string s;cin >> s;
        if (s[1] == 'C')sp[0].push_back(s);
        else if (s[1] == 'D')sp[1].push_back(s);
        else if (s[1] == 'H')sp[2].push_back(s);
        else sp[3].push_back(s);
    }
    vector<string>rk;
    for (int i = 0;i < 4;i++) {
        if (i == f)continue;
        sort(sp[i].begin(), sp[i].end());
        for (int j = 0;j < sp[i].size();j++)
            rk.push_back(sp[i][j]);
    }
    sort(sp[f].begin(), sp[f].end());
    for (int j = 0;j < sp[f].size();j++)
        rk.push_back(sp[f][j]);
 
    vector<pair<string, string>>ans;
    int cnt = 0;int p = rk.size() - 1;
    for (int i = 0;i < p;i++) {
        if (rk[i][1] == rk[i + 1][1]) {
            ans.push_back({ rk[i],rk[i + 1] });i++;
            cnt++;
        }
        else {
            if (f == 0 && rk[p][1] == 'C') {
                ans.push_back({ rk[i],rk[p] });p--;
            }
            else if (f == 1 && rk[p][1] == 'D') {
                ans.push_back({ rk[i],rk[p] });p--;
            }
            else if (f == 2 && rk[p][1] == 'H') {
                ans.push_back({ rk[i],rk[p] });p--;
            }
            else if (f == 3 && rk[p][1] == 'S') {
                ans.push_back({ rk[i],rk[p] });p--;
            }
            else {
                cout << "IMPOSSIBLE\n";return;
            }
        }
    }
    for (int i = 0;i < n;i++) {
        cout << ans[i].first << " " << ans[i].second << '\n';
    }
}

E-Final Countdown

题意

倒计时,但是每次变化数所需要的秒数等于要变化的数位的数量。

求实际上需要多少秒完成倒计时。

数据范围

思路

计数模拟:

12345
 1234
  123
   12
    1
-----+
13715

则对从第一位开始做前缀和,对(前缀和+进位)倒着取模,最后输出即可。

参考代码

void solve() {
    int n;cin >> n;
    string s;cin >> s;
    int x = 0;
    while (s[x] == '0') {
        x++;
    }
    s = s.substr(x);
    vector<ll>v;
    for (int i = 0;i < s.size();i++) {
        if (i != 0)
            v.push_back(v.back() + s[i] - '0');
        else {
            v.push_back(s[i] - '0');
        }
    }
    reverse(v.begin(), v.end());
    ll k = 0;
    vector<int>res;
    for (int i = 0;i < v.size();i++) {
        res.emplace_back((v[i] + k) % 10);
        k = (v[i] + k) / 10;
    }
    while(k > 0) {
        res.emplace_back(k % 10);
        k /= 10;
    }
    reverse(res.begin(), res.end());
    for (int i = 0;i < res.size();i++) {
        cout << res[i];
    }cout << '\n';
}