Atcoder Beginner contest 303 A~E

鼠鼠卡D题了,WA了两个样例,哭死力,打错了两字母

A- Similar String

题目链接
两个字符串a、b只有在 l1 或者 0o 时相似,判断a和b是否相似

  • 特殊判断一下
# include <bits/stdc++.h>
# define int long long
# define endl '\n'
# define x first
# define y second
# define INF 0x3f3f3f3f
# define pii pair<int, int>
# define uf(i, j, k) for (int i = j; i <= k; i ++)
# define df(i, j, k) for (int i = j; i >= k; i --)
# define mset(x, v) memset(x, v, sizeof x)

using namespace std;

void solve()
{
    int n;
    string a, b;
    cin >> n >> a >> b;
    bool ok = true;
    uf (i, 0, n - 1) 
    {
        if (a[i] == b[i]) continue;
        else if (a[i] != b[i])
        {
            if (a[i] == 'l' && b[i] == '1') continue;
            if (a[i] == '1' && b[i] == 'l') continue;
            if (a[i] == '0' && b[i] == 'o') continue;
            if (a[i] == 'o' && b[i] == '0') continue;
            ok = false;
            break;
        }
    }
    cout << (ok ? "Yes" : "No") << endl;
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    while (t --) solve();
    return 0;
}

B - Discord

题目链接
有m张照片,每张照片中n个人排成一排,判断有几对人从来没有站在旁边

  • 相邻的存在set里,特殊处理一下左右两边
  • 总的配对数减去存在set里面的数量
# include <bits/stdc++.h>
# define int long long
# define endl '\n'
# define x first
# define y second
# define INF 0x3f3f3f3f
# define pii pair<int, int>
# define uf(i, j, k) for (int i = j; i <= k; i ++)
# define df(i, j, k) for (int i = j; i >= k; i --)
# define mset(x, v) memset(x, v, sizeof x)

using namespace std;
const int N = 55;
int g[N][N];

void solve()
{
    int n, m;
    cin >> n >> m;
    set<pii> st;
    uf (i, 1, m)
    {
        uf (j, 1, n) cin >> g[i][j];
        st.insert({g[i][1], g[i][2]});
        st.insert({g[i][n - 1], g[i][n]});
        uf (j, 2, n - 1)
        {
            st.insert({g[i][j - 1], g[i][j]});
            st.insert({g[i][j], g[i][j - 1]});
            st.insert({g[i][j], g[i][j + 1]});
            st.insert({g[i][j + 1], g[i][j]});
        }
    }
    cout << (n * (n - 1) - st.size()) / 2 << endl;  
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t --) solve();
    return 0;
}

C - Dash

题目链接
高桥初始生命值为h,给一个移动字符串s,每移动一次都会扣掉一点生命值,有m个地方可以回复生命值,仅当h<k时才能回复且回复到k点,当生命值为负的时候无法移动,判断高桥能否完成移动。

  • 将补给点存一下
  • 根据所给的字符串s进行模拟移动
  • 当生命值为负数时停止移动
# include <bits/stdc++.h>
# define int long long
# define endl '\n'
# define x first
# define y second
# define INF 0x3f3f3f3f
# define pii pair<int, int>
# define uf(i, j, k) for (int i = j; i <= k; i ++)
# define df(i, j, k) for (int i = j; i >= k; i --)
# define mset(x, v) memset(x, v, sizeof x)
/*
    @see 
*/
using namespace std;

void solve()
{
    int n, m, h, k;
    cin >> n >> m >> h >> k;
    string s;
    cin >> s;
    map<pii, int> st;
    unordered_map<char, pii> mp({
        {'R', {1, 0}},
        {'U', {0, 1}},
        {'L', {-1, 0}},
        {'D', {0, -1}}
    });
    uf (i, 1, m) 
    {
        int x, y;
        cin >> x >> y;
        st[{x, y}] = 1;
    }
    int x = 0, y = 0, cur = 0;
    uf (i, 0, n - 1)
    {
        auto d = mp[s[i]];
        x += d.x, y += d.y;
        h --;
        if (h < 0) break;
        cur = i;
        if (st[{x, y}]) 
        {
            if (h < k) st[{x, y}] --, h = k;
        }
    }
    if (cur == n - 1 && h >= 0) cout << "Yes" << endl;
    else cout << "No" << endl;
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    while (t --) solve();
    return 0;
}

D - Shift vs. CapsLock

题目链接
单独按 a花费x时间, 同时按ashift花费y时间,单独按caps lock花费z时间,现在给一个仅含Aa的字符串s,求最小的花费时间
D

  • 两种状态,一个是到达当前位置caps lock开启的最小花费时间,一个是caps lock关闭的最小花费时间
  • 状态转移:
    • caps lock关闭状态可以由前一个位置的关闭状态(直接输入)dp[i - 1][off] + cost(cnt)或者开启状态(关闭后输入)dp[i - 1][on] + z + cost(cnt)转移过来
    • caps lock开启状态可以由前一个位置的关闭状态(开启后输入)dp[i - 1][on] + cost(cnt)或者开启状态(直接输入)dp[i - 1][off] + z + y * cnt转移过来
    • cost(cnt) 是指在caps lock开启或关闭的状态下输入所花费是的时间,根据前一个位置决定
  • 最终状态:取最后位置的两种状态的最小值即可
# include <bits/stdc++.h>
# define int long long
# define endl '\n'
# define x first
# define y second
# define INF 0x3f3f3f3f
# define pii pair<int, int>
# define uf(i, j, k) for (int i = j; i <= k; i ++)
# define df(i, j, k) for (int i = j; i >= k; i --)
# define mset(x, v) memset(x, v, sizeof x)

using namespace std;

void solve()
{
    int x, y, z;
    string s;
    cin >> x >> y >> z >> s;
    int n = s.length();
    s = " " + s;
    vector<vector<int>> dp(2);
    uf (i, 1, n)
    {
        int j = i;
        while (j <= n && s[i] == s[j]) j ++;
        int cnt = j - i;
        if (i == 1)
        {
            if (s[i] == 'a') 
            {
                dp[0].push_back(cnt * x); 
                dp[1].push_back(z + cnt * y);
            }
            else 
            {
                dp[0].push_back(cnt * y);
                dp[1].push_back(z + cnt * x);
            }
        }
        else 
        {
            int off = dp[0][dp[0].size() - 1], on = dp[1][dp[1].size() - 1];
            if (s[i] == 'a')
            {
                dp[0].push_back(min(off + x * cnt, on + z + x * cnt));
                dp[1].push_back(min(off + z + y * cnt, on + y * cnt));
            } 
            else 
            {
                dp[0].push_back(min(off + y * cnt, on + z + y * cnt));
                dp[1].push_back(min(off + z + x * cnt, on + x * cnt));
            }
        }
        i = j - 1;
    }
    cout << min(dp[0][dp[0].size() - 1], dp[1][dp[1].size() - 1]) << endl;
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t --) solve();
    return 0;
}

可以写更简洁一些,但是鼠鼠懒不想改了


E - A Gift From the Stars

题目链接
k级星图定义为中间一个结点,k 条边连接着k个结点的图
然后将若干个星图用一条边将它们的叶结点连接为一张图,共有N个结点N-1条边

  • 这实际是一棵树,然后我们需要找到星图的中心结点,然后统计其周围的结点数就是该星图的数目
  • 画图可以发现,每个星图的中心结点之间一定会隔着3倍数的边,那么我们从某一个中心结点x出发,当距离x为3的倍数时将其统计的结点数加入到答案中即可
  • 最后对答案数组进行排序输出
# include <bits/stdc++.h>
# define int long long
# define endl '\n'
# define x first
# define y second
# define INF 0x3f3f3f3f
# define pii pair<int, int>
# define uf(i, j, k) for (int i = j; i <= k; i ++)
# define df(i, j, k) for (int i = j; i >= k; i --)
# define mset(x, v) memset(x, v, sizeof x)
/*
    @see 
*/
using namespace std;
const int N = 2e5 + 5;
vector<vector<int>> e(N);
bool st[N];
int d[N];
vector<int> ans;
int n;
void solve()
{
    cin >> n;
    uf (i, 2, n) 
    {
        int a, b;
        cin >> a >> b;
        e[a].push_back(b);
        e[b].push_back(a);
        d[a] ++;  d[b] ++;
    }
    int s = 0;
    queue<pii> q;
    uf (i, 1, n) if (d[i] == 1) {q.push({e[i][0], 0}); break;}
    while (q.size()) {
        auto t = q.front(); q.pop();
        int u = t.x, dist = t.y;
        int cnt = 0;
        for (auto v : e[u]) 
        {
            if (!st[v]) q.push({v, dist + 1});
            st[v] = true;
            cnt ++;
        }
        if (dist % 3 == 0) ans.push_back(cnt);
    }
    sort(ans.begin(), ans.end());
    for (auto x : ans) cout << x << " ";
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t --) solve();
    return 0;
}

寻一颗 未萌的渺小啊
随着青翠未来 升入辽阔云霄
那些黑暗笼罩的 终将向阳而生呢

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值