2025牛客寒假算法基础集训营5 (摆烂版)

1 前言:

全队倒数,来写题解谢罪了[祥子_哭泣]

正在向AK反向全速前进 [马西洛_小哥]

2 题解

A 小L的三则运算

小模拟,取 xx±1 或者 1 即可。

void solve()
{
    int x;
    char o;
    cin >> x;
    cin >> o;
    if (o == '+')
    {
        cout << 1 << " " << x - 1 << endl;
    }
    else if (o == '-')
    {
        cout << x + 1 << " " << 1 << endl;
    }
    else
    {
        cout << 1 << " " << x  << endl;
    }
    
}

B 小L出师了

简单题,但不妨碍我狠狠吃罚时。
想象一下,将所有鸡课放置于左侧,L课放置于右侧,依次将右侧的L课插入左侧的鸡课,使鸡课尽可能长度等于t。是故取 min(k+1,(nk)t)

void solve()
{
    int n, t, k;
    cin >> n >> t >> k;
    int delta = t + 1;
    int ans = min(k+1, (n-k)/t);
    cout << ans << endl;
    
}

C 小L的位运算

神秘思维题,思路是和正解一模一样的,WA是没少的。

因为对于A,B二进制上的任意一位的两个,只有{0, 0}, {0, 1}, {1, 0}, {1, 1}四种状态,而只要任意两位是非法的,要么交换A行上的两个,要么交换B行上的两个,总能再一次交换上将两个非法位改成正确的。
那么非法的位置就不重要,就可以只考虑各种状态的数量了。先遍历一遍A,B,C,将二进制上的每一位的3位作为一组检验出所有非法的位置,把其按A,B的状态按{0, 0}, {0, 1}, {1, 0}, {1, 1}四种情况分类统计数量存进map里。
接下来判断一下:如果 X×2<Y ,那么简单直接全部用反置即可。反之,则需考虑两两对调至不可再操作后,再对剩下的反置。
前者不必多说,我们考虑后者。队友在这狠狠卡烂了,写了好几个if在哪嗯做,唉,分类讨论领域大神[YKN_摇头]。但实际上使用一个priority_queue存四类的数量,然后取第1,2大的一对一对消掉并统计对数即可。且对于任意堆数量,且最大的一堆的数量小于总数的一半时,以不同堆成对选取,最终会剩下 SUM % 2 个。

void solve()
{
    int n, x, y;
    cin >> n >> x >> y;
    string a, b, c;
    cin >> a >> b >> c;
    a = '0' + a;
    b = '0' + b;
    c = '0' + c;
    for (int i = 1; i <= n; i++)
    {
        if (a[i] != b[i] && c[i] == '0' || a[i] == b[i] && c[i] == '1')
        {
            mp[{a[i] - '0', b[i] - '0'}]++;
        }
    }


    if (x * 2 <= y)
    {
        int cnt = 0;
        for (auto iter : mp)
        {
            cnt += iter.second;
        }

        cout << cnt * x << endl;
    }
    else
    {
        
        priority_queue<int>pq;
        for (auto iter = mp.begin(); iter != mp.end(); iter++)
        {
            pq.push(iter->second);
        }
        int zweicnt = 0;
        int eincnt = 0;
        int nownum = 0;
        while (pq.size() > 1)
        {
            int fir = pq.top();
            pq.pop();
            int sec = pq.top();
            pq.pop();
            zweicnt += 1;
            fir -= 1;
            sec -= 1;
            if (fir > 0)
            {
                pq.push(fir);
            }
            if (sec > 0)
            {
                pq.push(sec);
            }
        }
        
        if (pq.size() > 0)
        {
            int fir = pq.top();
            pq.pop();
            eincnt += fir;
        }

        cout << eincnt * x + zweicnt*y << endl;
    }
}

E 小L的井字棋

分类讨论题。分类讨论领域大神发力了。
获胜情况只有3横,3竖,2斜。
1·所以对每一条获胜情况检查是否被放了对方的子,存在就无法获胜。
2·对于还有可能获胜的情况,检查如果存在有自己的子,因为我可以连放两个,可直接获胜。
3·而如果是什么都没有的话,检查能不能在两个可用获胜条件的重合点放子,可以的话获胜。
4·否则无绝对获胜的可能。

void solve()
{
    char s[4][4];
    for (int i = 1; i <= 3; i++)
        for (int j = 1; j <= 3; j++)
            cin >> s[i][j];
    int num[9] = {0};
    int road[9] = {0};
    if (s[1][1] == 'O')
        num[1] = num[4] = num[7] = 1;
    if (s[1][2] == 'O')
        num[1] = num[5] = 1;
    if (s[1][3] == 'O')
        num[1] = num[6] = num[8] = 1;
    if (s[2][1] == 'O')
        num[2] = num[4] = 1;
    if (s[2][2] == 'O')
        num[2] = num[5] = num[7] = num[8] = 1;
    if (s[2][3] == 'O')
        num[2] = num[6] = 1;
    if (s[3][1] == 'O')
        num[3] = num[4] = num[8] = 1;
    if (s[3][2] == 'O')
        num[3] = num[5] = 1;
    if (s[3][3] == 'O')
        num[3] = num[6] = num[7] = 1;
 
    int cnt = 0;
    for (int i = 1; i <= 8; i++)
    {
        for (int j = i + 1; j <= 8; j++)
        {
            if (!(i <= 3 && j <= 3 || (i >= 4 && i <= 6 && j >= 4 && j <= 6)))
            {
                if (num[i] == 0 && num[j] == 0)
                {
                    cout << "Yes" << endl;
                    return;
                }
            }
        }
    }
    int numg[4][4] = {};
    int numcopy[9] = {};
    for (int i = 1; i <= 3; i++)
    {
        for (int j = 1; j <= 3; j++)
        {
            if (s[i][j] == 'G')
                numg[1][i]++;
        }
    }
    for (int j = 1; j <= 3; j++)
        for (int i = 1; i <= 3; i++)
        {
            if (s[i][j] == 'G')
                numg[2][j]++;
        }
    for (int i = 1; i <= 3; i++)
        if (s[i][i] == 'G')
        {
            numg[3][1]++;
        }
    for (int i = 1; i <= 3; i++)
    {
        if (s[i][4 - i] == 'G')
        {
            numg[3][2]++;
        }
    }
    numcopy[1] = numg[1][1], numcopy[2] = numg[1][2], numcopy[3] = numg[1][3], numcopy[4] = numg[2][1], numcopy[5] = numg[2][2], numcopy[6] = numg[2][3], numcopy[7] = numg[3][1], numcopy[8] = numg[3][2];
    for (int i = 1; i <= 8; i++)
    {
        if (num[i] == 0 && numcopy[i] != 3)
        {
            cout << "Yes" << endl;
            return;
        }
    }
    cout << "No" << endl;
}

I 小L的数学题

注意力小数论题。考虑到n除了0之外都能能直接根号成1,当时直接猜出来了使用翻倍和开方可以从1得到任意非负数。

严格证明请看官方题解点我点我

void solve()
{
    int n, m;
    cin >> n >> m;
    if (n == m)
    {
        cout << "Yes" << endl;
        return;
    }
    else if ((n == 0 && m != 0) || (n!=0 && m==0))
    {
        cout << "No" << endl;
        return;
    }
    

    cout << "Yes" << endl;
}

J 小L的汽车行驶问题

纯模拟,没有什么特别的。

void solve()
{
    int n;
    cin >> n;
    string str;
    cin >> str;
    str = '@' + str;
    int nowv = 0;
    int len = 0;
    int nexaddv = -1;
    for (int i = 1; i <= n; i++)
    {

        int op = str[i];
        if (nexaddv != -1)
        {
            nowv = nexaddv;
            nexaddv = -1;
        }

        
        if (op == '0')
        {
            nowv += 10;
        }
        else if (op == '1')
        {
            nowv -= 5;
            if (nowv < 0)
            {
                nowv = 0;
            }
        }
        else
        {
            nexaddv = nowv;
            nowv -= 10;
            if (nowv < 0)
            {
                nowv = 0;
            }
            
        }

        len += nowv;
    }

    cout << len << endl;
}

3 总结

这场难度分化,简单和困难都比较多,中间难度少,而且比较考注意力。只能说这类型我确实还要加强。

posted @   青一凡  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示