牛客周赛 Round 34

牛客周赛 Round 34

小红的字符串生成

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;

void solve()
{
    string a, b;
    cin >> a >> b;
    if (a == b)
    {
        cout << 2 << endl;
        cout << b << endl;
        cout << a + b << endl;
    }
    else
    {
        cout << 4 << endl;
        cout << a << endl;
        cout << b << endl;
        cout << a + b << endl;
        cout << b + a << endl;
    }
}

int main()
{
    int t = 1;
    // cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

小红的非排列构造

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;

void solve()
{
    int n;
    cin >> n;
    vector<int> a(n + 1);
    int cnt = 1;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        if (a[i] != i)
        {
            cnt = 0;
        }
    }
    cout << cnt << endl;
    if (cnt)
    {
        cout << 1 << ' ' << n << endl;
    }
}

int main()
{
    int t = 1;
    // cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

小红的数字拆解

解题思路:

从前往后拆,遇到偶数就分,最后记得排序。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;

bool cmp(string a, string b)
{
    if (a.size() != b.size())
    {
        return a.size() < b.size();
    }
    return a < b;
}

void solve()
{
    string s;
    cin >> s;
    string cur;
    vector<string> t;
    for (auto c : s)
    {
        cur += c;
        int x = c - '0';
        if (!(x & 1))
        {
            if (cur.size())
            {
                t.emplace_back(cur);
            }
            cur.clear();
        }
    }
    sort(t.begin(), t.end(), cmp);
    for (auto c : t)
    {
        cout << c << endl;
    }
}

int main()
{
    int t = 1;
    // cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

小红的陡峭值

解题思路:

设出现了x个大于零的数。

  • x=0:构造序列(2,1,1,...,1)

  • x=1:如果序列首尾都不为零,那么无解。否则首尾取一个作为出现数字加一。

  • x=2:若两数之差大于1,无解。

    否则,设最左边出现的非零数为a,设最右边出现的非零数为b。从左开始向右赋值a,直到遇到非零且非a的数停止,右侧同理。最后按题意判断序列陡峭值是否为1

  • x>2:无解。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;

void solve()
{
    int n;
    cin >> n;
    vector<int> a(n + 1);
    set<int> s;
    ll res = 0;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        if (a[i] > 0)
        {
            s.insert(a[i]);
        }
    }
    if (s.size() > 2)
    {
        puts("-1");
        return;
    }
    if (s.size() == 0)
    {
        for (int i = 1; i <= n; i++)
        {
            if (i == 1)
            {
                cout << 2 << ' ';
                continue;
            }
            cout << 1 << ' ';
        }
    }
    else if (s.size() == 1)
    {
        int x = *s.begin();
        if (a[1] == 0)
        {
            a[1] = x + 1;
            for (int i = 1; i <= n; i++)
            {
                if (i != 1)
                {
                    cout << x << ' ';
                    continue;
                }
                cout << a[i] << ' ';
            }
        }
        else if (a[n] == 0)
        {
            a[n] = x + 1;
            for (int i = 1; i <= n; i++)
            {
                if (i != n)
                {
                    cout << x << ' ';
                    continue;
                }
                cout << a[i] << ' ';
            }
        }
        else
        {
            puts("-1");
        }
    }
    else
    {
        int x = *s.begin();
        int y = *s.rbegin();
        if (abs(x - y) > 1)
        {
            cout << -1 << endl;
            return;
        }
        vector<int> v(13);
        for (int i = 1; i <= n; i++)
        {
            if (a[i] != 0)
            {
                v[1] = a[i];
                break;
            }
        }
        for (int i = n; i; i--)
        {
            if (a[i] != 0)
            {
                v[2] = a[i];
                break;
            }
        }
        for (int i = 1; i <= n; i++)
        {
            if (a[i] != 0 && a[i] != v[1])
            {
                break;
            }
            a[i] = v[1];
        }
        for (int i = n; i; i--)
        {
            if (a[i] != 0 && a[i] != v[2])
            {
                break;
            }
            a[i] = v[2];
        }
        ll t = 0;
        for (int i = 2; i <= n; i++)
        {
            t += abs(a[i] - a[i - 1]);
        }
        if (t == 1)
        {
            for (int i = 1; i <= n; i++)
            {
                cout << a[i] << ' ';
            }
        }
        else
        {
            puts("-1");
        }
    }
}

int main()
{
    int t = 1;
    // cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

小红的树形 dp

解题思路:

dp[i][0/1]:ii(d/p)

如果有解,那么顺着构造即可。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;
const int N = 1e5 + 10;
const int inf = 1 << 30;
vector<int> e[N];
int n;
string s;
int ans[N];
bool dp[N][2];

void dfs(int u, int fa)
{
    if (s[u] == 'd')
    {
        dp[u][0] = 1;
        dp[u][1] = 0;
    }
    else if (s[u] == 'p')
    {
        dp[u][1] = 1;
        dp[u][0] = 0;
    }
    else
    {
        dp[u][0] = dp[u][1] = 1;
    }
    for (auto v : e[u])
    {
        if (v == fa)
        {
            continue;
        }
        dfs(v, u);
        dp[u][0] = dp[u][0] & dp[v][1];
        dp[u][1] = dp[u][1] & dp[v][0];
    }
}

void dfs_solve(int u, int fa, int par)
{
    ans[u] = par ^ 1;
    for (auto v : e[u])
    {
        if (v == fa)
        {
            continue;
        }
        dfs_solve(v, u, par ^ 1);
    }
}

void solve()
{
    cin >> n;
    cin >> s;
    s = ' ' + s;
    for (int i = 1; i < n; i++)
    {
        int a, b;
        cin >> a >> b;
        e[a].emplace_back(b);
        e[b].emplace_back(a);
    }
    dfs(1, -1);
    if (!(dp[1][0] | dp[1][1]))
    {
        puts("-1");
    }
    else
    {
        if (dp[1][0])
        {
            dfs_solve(1, -1, 1);
        }
        else
        {
            dfs_solve(1, -1, 0);
        }
        for (int i = 1; i <= n; i++)
        {
            char c = ans[i] == 1 ? 'p' : 'd';
            cout << c;
        }
    }
}

int main()
{
    int t = 1;
    // cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

小红的矩阵构造

解题思路:

注意:x为偶数。尝试构造,最终每行每列的异或和都是0

  • x%4=0:将x/4填入左上方四个格子。
  • x%4=2
    • x=2:无解。
    • x=6:我们发现,可以将61填入右下角,使得最终每行每列的异或和都是0
    • x>6:只要不是n=m=4,都有解。结合上述方法先减去6,在填入左上角。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;

void solve()
{
    int n, m, x;
    cin >> n >> m >> x;
    vector<vector<int>> g(n + 1, vector<int>(m + 1));
    if (x % 4 == 0)
    {
        x /= 4;
        g[1][1] = g[1][2] = g[2][1] = g[2][2] = x;
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= m; j++)
            {
                cout << g[i][j] << ' ';
            }
            cout << endl;
        }
    }
    else
    {
        if (x == 2 || (n == m && n == 4 && x > 6))
        {
            puts("-1");
        }
        else if (x == 6)
        {
            x -= 6;
            g[n][m] = g[n - 1][m - 1] = g[n - 2][m - 2] = g[n - 2][m - 1] = g[n - 1][m] = g[n][m - 2] = 1;
            for (int i = 1; i <= n; i++)
            {
                for (int j = 1; j <= m; j++)
                {
                    cout << g[i][j] << ' ';
                }
                cout << endl;
            }
        }
        else
        {
            x -= 6;
            g[n][m] = g[n - 1][m - 1] = g[n - 2][m - 2] = g[n - 2][m - 1] = g[n - 1][m] = g[n][m - 2] = 1;
            x /= 4;
            g[1][1] = g[1][2] = g[2][1] = g[2][2] = x;
            for (int i = 1; i <= n; i++)
            {
                for (int j = 1; j <= m; j++)
                {
                    cout << g[i][j] << ' ';
                }
                cout << endl;
            }
        }
    }
}

int main()
{
    int t = 1;
    // cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

小红的元素交换

解题思路:

排列交换到升序,构造置换环。

环有三种,纯红,纯白,红白。

纯的本身都无法移动元素;红白和正常置换环一样,元素数减一次操作即可完成置换。

将一个纯红和一个纯白合并成红白需要一步,纯加红白变为红白也只需要一步,但明显先合并纯色更优。

注意:元素数量为一的环,也就是自环,看情况使用。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
using piii = pair<ll, pair<ll, ll>>;

void solve()
{
    int n;
    cin >> n;
    vector<int> a(n + 1), ne(n + 1);
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
    }
    string s;
    cin >> s;
    s = ' ' + s;
    bool us = true;
    for (int i = 1; i <= n; i++)
    {
        if (a[i] != i)
        {
            us = false;
        }
    }
    if (us)
    {
        puts("0");
        return;
    }
    for (int i = 1; i <= n; i++)
    {
        ne[i] = a[i];
    }
    vector<bool> vis(n + 1);
    vector<int> vr, vw, vh;
    for (int i = 1; i <= n; i++)
    {
        int u = i;
        if (vis[a[u]])
        {
            continue;
        }
        vector<int> cnt(2, 0);
        while (!vis[a[u]])
        {
            vis[a[u]] = true;
            if (s[a[u]] == 'R')
            {
                cnt[0]++;
            }
            else
            {
                cnt[1]++;
            }
            u = ne[u];
        }
        if (cnt[0] && cnt[1])
        {
            vh.emplace_back(cnt[0] + cnt[1]);
        }
        else if (cnt[0])
        {
            vr.emplace_back(cnt[0]);
        }
        else
        {
            vw.emplace_back(cnt[1]);
        }
    }
    ll ans = 0;
    if (vh.empty() && (vr.empty() || vw.empty()))
    {
        puts("-1");
        return;
    }
    sort(vr.begin(), vr.end());
    sort(vw.begin(), vw.end());
    while (vr.size() > 0 && vw.size() > 0)
    {
        int x = vr.back();
        int y = vw.back();
        int h = vr.back() + vw.back();
        if ((x == 1 || y == 1) && vh.size() > 0)
        {
            break;
        }
        vr.pop_back();
        vw.pop_back();
        vh.push_back(h);
        ans++;
    }
    while (vr.size() > 0)
    {
        int x = vr.back();
        int t = vh.back() + vr.back();
        if (x == 1)
        {
            break;
        }
        vh.pop_back();
        vr.pop_back();
        vh.emplace_back(t);
        ans++;
    }
    while (vw.size() > 0)
    {
        int y = vw.back();
        int t = vh.back() + vw.back();
        if (y == 1)
        {
            break;
        }
        vh.pop_back();
        vw.pop_back();
        vh.emplace_back(t);
        ans++;
    }
    for (auto x : vh)
    {
        ans += x - 1;
    }
    cout << ans << endl;
}

int main()
{
    int t = 1;
    // cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}
posted @   value0  阅读(95)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示