牛客多校第六场 B Shorten IPv6 Address 模拟

题意:

给你一个二进制表示的IPv6地址,让你把它转换成8组4位的16进制,用冒号分组的表示法。单组的前导0可以省略,连续多组为0的可以用两个冒号替换,但是只允许替换一次。把这个地址通过这几种省略方式,长度缩到最短,然后输出字典序最小的。

题解:

计算出八组四位16进制数的值,找出连续的0,用冒号替换即可。

坑点:1,替换连续的0的时候,一定要注意冒号不能多加

2,题目要求字典序最小,因为冒号的ascii值大于0,那就优先替换后面的,但是,同样长度的连续0,替换掉中间的,比替换掉两边的,最后得到的长度要短1,因此要优先替换掉中间的。

#include<iostream>
#include<cstring>
#include<string>
using namespace std;
char ip[2005],fl[30];
int count[26];
int qj[10];
int main(){
//    printf("%d",'9');
//0=48 :=58 省略最右边的 
//
    int k;
    scanf("%d",&k);
    for(int I=1;I<=k;I++){
        scanf("%s",ip);
        int l=128;
//        msmset(qj,0,sizeof qj);
        for(int i=0;i<8;i++){
            qj[i]=0; 
            for(int j=0;j<16;j++){
                qj[i]<<=1;
                qj[i]+=ip[i*16+j]-'0';
            }
        }
        int lx0=0,lx0max=0,lx0over=0;
    
        for(int i=7;i>=0;i--){
            if(qj[i]==0){
                lx0++;
                if(lx0>lx0max){
                    lx0over=i;
                    lx0max=lx0;
                }else if(lx0==lx0max){
                    if(lx0over+lx0max==8 && i!=0){
                        lx0over=i;
                        lx0max=lx0;
                    }
                }
            }else{
                lx0=0;
            }
        }
        
        printf("Case #%d: ",I); 
        bool alrdy=0;
        
        for(int i=0;i<8;i++){
            if(lx0max>=2 && lx0over==i){
                if(alrdy==0)printf("::");
                else printf(":");
                alrdy=1;
                i+=lx0max-1;
            }else{
                printf("%x",qj[i]);
                alrdy=0;
                if(i<7){
                    printf(":");
                    alrdy=1;
                }
            }
        }
        printf("
");
    }
} 
原文地址:https://www.cnblogs.com/isakovsky/p/11296386.html