1 条题解

  • 0
    @ 2025-8-24 21:14:54

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar zengyongxu
    「不积跬步无以至千里,不积小流无以成江海。」

    搬运于2025-08-24 21:14:53,当前版本为作者最后更新于2025-05-18 18:56:40,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    B3760 [信息与未来 2021] 掷骰子 题解

    写在前面

    下文中图片可能字不是很好看,如果需调整指出即可。

    UPD 7/27 将图床链接更新

    正片

    首先,这道题的这一个部分很吸引人:

    0n200\leq n\leq 20

    的确,这提示了这题的一个不错的想法:暴力枚举,检验。

    第一部分:暴力枚举

    非常容易(不用想象中复杂的深搜),只需要一个六重循环即可。

    随后根据题意修改:

    int mn = 50, mx = 1;
    for (a = 1; a <= 6; a++)
    {
        for (b = 1; b <= 6; b++)
        {
            for (c = 1; c <= 6; c++)
            {
                for (d = 1; d <= 6; d++)
                {
                    for (e = 1; e <= 6; e++)
                    {
                        for (f = 1; f <= 6; f++)
                        {
                            int sum = a + b + c + d + e + f;
                            if (judge()){
                                mn = min(mn, sum);
                                mx = max(mx, sum);
                            }
                        }
                    }
                }
            }
        }
    }
    

    第二部分:检验

    根据上文所说,我们需要一个用于检验的函数。

    那么代码:

    bool judge()
    {
        // ...
    }
    

    然后,我们只需要枚举每一个条件,看看有没有符合的。

    那么代码:

    bool judge()
    {
        for (int i = 1; i <= n; i++)
        {
            // ...
        }
        return true;
    }
    

    接下来对循环里面的判断条件进行思考:

    这里采取一种暴力的方式来映衬上面暴力的枚举:直接枚举每一种拍摄角度,判断是否和条件吻合即可,不过我们需要一些准备。

    首先,我们计算不同角度拍摄的方案总数:一共有六个面,对于每个面在顶上,一共有四种拍摄角度,即:6×4=246\times 4 = 24

    那么,我们先画24个正方体:

    随后,根据上面的计算,每个面作为顶有4个角度,于是我们把每个正方体的顶部画出来:

    接着,只需要拿一个长方体(我选用了牛奶盒),六个面分别标上:abcdef

    出示一下我的标注字母的图片,以便下文描述。

    众所周知,正方体展开图是六上第一个单元的内容。

    接下来,以每个面为顶,转动长方体,记录剩余两个面的字母。

    以下是我的结果:

    那么判断函数也就能写出来了。这里的代码太长了,我就不出示了,毕竟在最后代码里也有的。

    小技巧:

    可以用:uvw来代替:xi,yi,zix_i,y_i,z_i以减少代码量。

    你们期待的 AC 代码!你的键盘上不只有 ctrl, c, v 这三个键!

    不要贬我的码风555...

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 25;
    
    int n, x[N], y[N], z[N];
    int a, b, c, d, e, f;
    
    bool judge()
    {
        for (int i = 1; i <= n; i++)
        {
            int u = x[i], v = y[i], w = z[i];
            if (u == a && v == c && w == d)
                continue;
            if (u == a && v == d && w == f)
                continue;
            if (u == a && v == f && w == b)
                continue;
            if (u == a && v == b && w == c)
                continue;
    
            if (u == b && v == e && w == c)
                continue;
            if (u == b && v == c && w == a)
                continue;
            if (u == b && v == a && w == f)
                continue;
            if (u == b && v == f && w == e)
                continue;
    
            if (u == c && v == e && w == d)
                continue;
            if (u == c && v == d && w == a)
                continue;
            if (u == c && v == a && w == b)
                continue;
            if (u == c && v == b && w == e)
                continue;
    
            if (u == d && v == e && w == f)
                continue;
            if (u == d && v == f && w == a)
                continue;
            if (u == d && v == a && w == c)
                continue;
            if (u == d && v == c && w == e)
                continue;
    
            if (u == e && v == f && w == d)
                continue;
            if (u == e && v == d && w == c)
                continue;
            if (u == e && v == c && w == b)
                continue;
            if (u == e && v == b && w == f)
                continue;
    
            if (u == f && v == e && w == b)
                continue;
            if (u == f && v == b && w == a)
                continue;
            if (u == f && v == a && w == d)
                continue;
            if (u == f && v == d && w == e)
                continue;
    
            return false;
        }
        return true;
    }
    
    int main()
    {
        cin >> n;
        for (int i = 1; i <= n; i++)
        {
            cin >> x[i] >> y[i] >> z[i];
        }
    
        int mn = 50, mx = 0;
        for (a = 1; a <= 6; a++)
        {
            for (b = 1; b <= 6; b++)
            {
                for (c = 1; c <= 6; c++)
                {
                    for (d = 1; d <= 6; d++)
                    {
                        for (e = 1; e <= 6; e++)
                        {
                            for (f = 1; f <= 6; f++)
                            {
                                if (judge())
                                {
                                    mn = min(mn, a + b + c + d + e + f);
                                    mx = max(mx, a + b + c + d + e + f);
                                }
                            }
                        }
                    }
                }
            }
        }
    
        cout << mn << " " << mx << "\n";
    }
    

    本蒟蒻耗费快两个月写完的 (我只有周末或者放假有空),重审多次,有错请指出,求赞 qwq。

    • 1

    信息

    ID
    8623
    时间
    1000ms
    内存
    128MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者