2 条题解

  • 1
    @ 2025-4-17 11:15:34

    题目说: 可以将其中相邻的值为0的段合并压缩起来

    感觉有问题,因为最终答案应该是把只有一个零的情况也计算上了,也就是按照标准ipv6去压缩。

        static final long MOD = (long) 1e9 + 7;
    
        private static void solve()
        {
    //        System.out.println((1 << 4));
    //        System.out.println((1 << 4 * 2) - (1 << 4));
    //        System.out.println((1 << 4 * 3) - (1 << 4 * 2));
    //        System.out.println((1 << 4 * 4) - (1 << 4 * 3));
    //        System.out.println(65536);
            long[] a = {16, 240, 3840, 61440}; // 分别代表长度为1,2,3,4的次数
            
            long res = 0;
            for (int i1 = 0; i1 < 4; i1++)
                for (int i2 = 0; i2 < 4; i2++)
                    for (int i3 = 0; i3 < 4; i3++)
                        for (int i4 = 0; i4 < 4; i4++)
                            for (int i5 = 0; i5 < 4; i5++)
                                for (int i6 = 0; i6 < 4; i6++)
                                    for (int i7 = 0; i7 < 4; i7++)
                                        for (int i8 = 0; i8 < 4; i8++) // 八位,每一位四种情况全部枚举
                                        {
                                            long part = 1;
                                            part = part * a[i1] % MOD * a[i2] % MOD * a[i3] % MOD * a[i4] % MOD;
                                            part = part * a[i5] % MOD * a[i6] % MOD * a[i7] % MOD * a[i8] % MOD;
                                            part = part * (i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + 8 + 7) % MOD;
                                            res = (res + part) % MOD; // 上面的 +7 是(马嘉祺bushi)没去冒号的个数
                                        }
    
            for (int i = 0; i < 256; i++)
            {
                String s = Integer.toBinaryString(i); // 转二进制
                int len = maxLen(s);
    
    //            System.out.println(" " + len); // 输出每一种的二进制最长要去的大小
                if (len <= 0) continue;
                long part = len;
                for (int j = 0; j < s.length(); j++) // 枚举要去0的所有可能
                {
                    if (s.charAt(j) == '1') part = (part * 65535) % MOD; // 因为最大65536,去0这种可能就是65535
                }
    
                res = (res + MOD - part) % MOD;
            }
    
            System.out.println(res);
        }
    
        private static int maxLen(String s)
        {
            int len = s.length();
            for (int i = 0; i < 8 - len; i++) s = "0" + s;
    
    //        System.out.print(s); // 输出每一种的二进制情况
            String zero = "00000000";
            for (int i = 8; i >= 1; i--) // 从大的开始暴力枚举每一个,判断字符串里面有没有
            {
                int in = s.indexOf(zero.substring(0, i));
                if (in + i >= s.length() && in == 0) return i * 2 - 3; // 0000-0000这种情况,要留2个冒号
                else if (in + i >= s.length()) return i * 2 - 2; // 最大的在最后的情况,要留1个冒号
                else if (in > 0) return i * 2 - 1; // 最大的在中间的情况,不用留冒号
                else if (in == 0) // 最大的在前面的情况,还要判断相同大小在不在中间
                {
                    int inn = s.substring(1).indexOf(zero.substring(0, i));
                    if (inn != -1 && inn + i < s.length() - 1) return i * 2 - 1; // 最大的在中间和开头的情况,取最小不用留冒号的情况
                    else return i * 2 - 2; // 大的在最后和开头的情况,要留1个冒号
                }
            }
            return 0; // 代表找不到0
        }
    

    信息

    ID
    36
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    7
    已通过
    3
    上传者