挖土机周赛R0

http://acm.mangata.ltd/d/system/contest/65a4b6d9b13e94c47857628c

T1 卖水果

思路

简单的讲三种情况模拟出来选一个max即可

#include <bits/stdc++.h>
using namespace std;
int n, x, y;
int a1, a2, a3, a4;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> x >> y;
    cin >> a1 >> a2 >> a3 >> a4;
    int plan1 = (n / 10) * 4 * x;
    int plan2 = (n / 2) * y;
    int plan3 = (a1 + a2 + a3 + a4) * n;
    //cout << plan1 << " " << plan2 << " " << plan3 << "\n";
    if (plan1 > plan2 && plan1 > plan3)
    {
        cout << plan1 << "\n";
    }
    else if (plan2 > plan3)
    {
        cout << plan2 << "\n";
    }
    else
    {
        cout << plan3 << "\n";
    }
    return 0;
}

T2 算得分

思路

按照要求模拟每道题的分数,最后输出总和

#include <bits/stdc++.h>
using namespace std;
int T, s, n, sum;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> T;
    while (T--)
    {
        cin >> s >> n;
        int base = s * 7 / 10;
        for (int i = 1; i <= n; i++)
            s = s * 95 / 100;
        sum += max(s, base);
    }
    cout << sum << "\n";
    return 0;
}

T3 WOTOJO

思路

我们只需要去枚举s中出现w的位置,然后从w出现的位置一直完整匹配到子串wotojo即可

每一次匹配到的子串我们对其取一个最小的长度(初始长度设为INF或者字符串长度都可)

#include <bits/stdc++.h>
using namespace std;
string s;
string t = "wotojo";
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> s;
    int ans = s.size();
    for (int i = 0; i < s.size(); i++)
    {
        if (s[i] != 'w')
            continue;
        int now = 1; // 下一个要查询的字符为 t[now]
        for (int j = i + 1; j < s.size(); j++)
        {
            // 匹配上最近的一个
            if (s[j] == t[now])
                now++;
            if (now == 6)
            {
                // 到 j 的位置时六个字符都找到了
                // 即 s[i] ~ s[j] 这个子串中存在子序列 wotojo
                // 显然这是 i 开头最短的子串
                ans = min(ans, j - i + 1);
                break;
            }
        }
    }
    cout << ans << "\n";
    return 0;
}

T4 三子棋

思路

因为要三子一线,其实就可以分为两种情况

    1. 第一种则是当前位置下的棋子作为端点(三子一线有两个端点)
    1. 第二种则是当前位置下的棋子作为中间点

对于前者我们不需要关心是左端还是右端,对于整个棋盘我们只需要遍历所有未下子位置的八个方向即可,如果当前方向外已经有两个棋子(这里需要注意棋盘的输入),则计数加一

#include <bits/stdc++.h>
using namespace std;
int n, m;
char g[55][55];
// 左上、上、右上、左、右、左下、下右下
int dx[] = {0, -1, -1, -1, 0, 0, 1, 1, 1};
int dy[] = {0, -1, 0, 1, -1, 1, -1, 0, 1};
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> m;
    for (int i = 2; i <= n + 1; i++)
        for (int j = 2; j <= m + 1; j++)
            cin >> g[i][j];
    int ans = 0;
    for (int i = 2; i <= n + 1; i++)
        for (int j = 2; j <= m + 1; j++)
        {
            if (g[i][j] == '#')
                continue;
            bool flag = false;
            // 作为端点的八个方向
            for (int k = 1; k <= 8; k++)
            {
                int x = i + dx[k];
                int y = j + dy[k];
                int xx = i + 2 * dx[k];
                int yy = j + 2 * dy[k];
                if (g[x][y] == '#' && g[xx][yy] == '#')
                {
                    flag = true;
                    break;
                }
            }
            if (flag)
            {
                ans++;
                continue;
            }
            // 作为中间点的四个方向
            for (int k = 1; k <= 4; k++)
            {
                int x = i + dx[k];
                int y = j + dy[k];
                int xx = i - dx[k];
                int yy = j - dy[k];
                if (g[x][y] == '#' && g[xx][yy] == '#')
                {
                    flag = true;
                    break;
                }
            }
            if (flag)
                ans++;
        }
    cout << ans << "\n";
    return 0;
}

0 comments

No comments so far...