2019牛客暑期多校训练营(六)-B(模拟)-Shorten IPv6 Address

2019牛客暑期多校训练营(第六场)B-Shorten IPv6 Address

题目链接: B-Shorten IPv6 Address.

题目描述

           \;\;\;\;\; 给一个 I P v 6 IPv6 IPv6 地址,以一个长度为 128 128 128 位的二进制串表示,对这个地址进行化简。化简规则如下:
           \;\;\;\;\; 将二进制转换为16进制,从前往后,每4位为一个区域,以 " : " ":" ":" 分隔;
           \;\;\;\;\; 每个区域的前导 0 0 0 可以删除;
           \;\;\;\;\; 若连续两个及以上的区域为0,可将其用 “ : : ” “::” :: 代替,代替只能使用至多一次。

           \;\;\;\;\; 求:化简后最短的地址,若存在多个,输出字典序最小的。
           \;\;\;\;\; 1 ≤ T ≤ 1000 1\leq T \leq 1000 1T1000.

思路

       \;\;\; 又是一场以一人之力对抗…虽然我也很菜,但是还是想吐槽一下不好好干活的队友
       \;\;\; 首先保证长度最短,有多个长度的连续 0 0 0,肯定选择最长的化简。
&ThickSpace;&ThickSpace;&ThickSpace; \;\;\; 多个长度相同的连续 0 0 0,比如 0 : 0 : 0 : 1 : 1 : 0 : 0 : 0 0:0:0:1:1:0:0:0 0:0:0:1:1:0:0:0,根据字典序最小,选择靠后的区域化简。 e g : eg: eg: &quot; 0 : 0 : 0 : 1 : 1 : : &quot; &lt; &quot; : : 1 : 1 : 0 : 0 : 0 &quot; &quot;0:0:0:1:1::&quot; &lt; &quot;::1:1:0:0:0&quot; "0:0:0:1:1::"<"::1:1:0:0:0".
&ThickSpace;&ThickSpace;&ThickSpace; \;\;\; 然而我忽略了一个坑点,那就是,长度相同的连续 0 0 0,首尾和中间的贡献不同。
&ThickSpace;&ThickSpace;&ThickSpace; \;\;\; e g : eg: eg: “ 0 : 0 : 1 : 0 : 0 : 1 : 0 : 0 ” → “ 0 : 0 : 1 : 0 : 0 : 1 : : ” “0:0:1:0:0:1:0:0”\rightarrow “0:0:1:0:0:1::” 0:0:1:0:0:1:0:00:0:1:0:0:1::.
&ThickSpace;&ThickSpace;&ThickSpace; \;\;\; &ThickSpace;&ThickSpace;&ThickSpace; \;\;\; &ThickSpace;&ThickSpace; \;\; “ 0 : 0 : 1 : 0 : 0 : 1 : 0 : 0 ” → “ 0 : 0 : 1 : : 1 : 0 : 0 ” “0:0:1:0:0:1:0:0”\rightarrow “0:0:1::1:0:0” 0:0:1:0:0:1:0:00:0:1::1:0:0.

代码

#include <bits/stdc++.h>
  
using namespace std;
  
const int MAXN = 200;
#define EPS (1e-10)
  
int b[MAXN], c[MAXN];
int main() {
    int T;
    int Len3 = 8;  
    scanf("%d", &T);
    for(int tt = 1; tt <= T; tt++) {
        for(int i = 1; i <= 8; i++) {
        	int x = 0, s;
        	for(int j = 1; j <= 16; j++) {
        		scanf("%1d",&s);
	            x = x*2 + s;    		
			}
			b[i] = x;
		}
        for(int i = 1; i <= 10; i++) c[i] = 0; c[0] = 100;
        int l = 0;
        for(int i = 1; i <= Len3; i++) {
            if(b[i] == 0) l++;
            else if(l > 0) {
                c[l] = i - l;
                l = 0;
            }
        }
        if(l > 0 && c[l] <= 1) c[l] = Len3 - l + 1;
        bool flag = 0;
        printf("Case #%d: ",tt);
        for(int i = 8; i >= 2;i--) {
            if(c[i] > 0) {
                for(int j = 1; j <= 8; j++) {
                    if(j == c[i]) {
                        flag = 1;
                        printf("::");
                        j = j + i - 1;
                    }
                    else {
                    	printf("%x", b[j]);
                        if(j < 8 && flag || (!flag && (j+1) != c[i])) printf(":");
                    }                     
                }
                printf("\n");
                flag = 1;
                break;
            }
        }
        if(!flag) {
            for(int i = 1; i <= 8; i++) {
             	printf("%x%c", b[i],":\n"[i==8]); // 优秀的写法,虽然我还不懂 
            }
        }  
    }
    return 0;
}

错误点

&ThickSpace;&ThickSpace;&ThickSpace;&ThickSpace;&ThickSpace; \;\;\;\;\; 字符串模拟题。题解说推荐学习所有提交中最短的几份代码的写法。感觉差距挺大。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值