2019牛客暑期多校训练营(六)

声明:本文章题目来源均为牛客网

链接:https://ac.nowcoder.com/acm/contest/886#question

A-Garbage Classification

一道垃圾分类题(2333),签到就不讲了。

B-Shorten IPv6 Address

题目类型:进制转换,思维模拟

题目链接:https://ac.nowcoder.com/acm/contest/886/B

题目大意

给一个01二进制字符串地址,一共有128个字符,然后确定它的最短表示

以十六进制表示形式表示地址,并使用冒号 ' : ' 分割每四个十六进制数字。每四个数字称为一个字段,例如:

00000000000000000000000000000000000000010010001101000101011001111000100110101011000000000000000000000000000000000000000000000000

转化为下面的形式(这里的:是中文字符,为了方便演示,写代码的时候注意下中英文

0000:0000:0123:4567:89ab:0000:0000:0000

可以省略字段中的前导零。例如上面的十六进制表示为:

0:0:123:4567:89ab:0:0:0

由至少两个字段组成的连续零字段(包括靠近它们的冒号)可以用双冒号'::'替换。此外,地址中不能使用多个双冒号

例如,上面的IPv6地址可以缩短为0:0:123:4567:89ab ::或:: 123:4567:89ab:0:0:0,但不能缩写为:: 123:4567: 89ab ::。

如果有多个相同长度的最短格式,请使用字典(将缩短的IPv6地址视为字符串)最小的一个

题目理解

二进制转换成十六进制的方法是,取四合一法,所以16个二进制数字可转换为4个十六进制数字,而c语言里有现成的16进制的输出方式(%x),

so,我们可以把128个字符里每16个字符表示的十进制数字用数组存起来,然后输出的时候用%x输出每个数字就行了(转换成数字还可以去掉前导零)。

不过还要考虑题目所说的最短的输出,所以还要考虑连续的数字0的最长长度。而且题目说了相同长度的串要求输出字典序最小的那一个,查一下ASCII表,发现' : '大于' 0 ',所以应该尽量输出最长长度0数字连续子串在中间的字符串或者靠后的。

比如0:0:123:4567:89ab ::或:: 123:4567:89ab:0:0:0应该输出第一个。

题目代码

#include<iostream>
#define sc(x) scanf("%d",&x); //方便输入
using namespace std;
int main(){
    int t,x;sc(t);x=t;getchar();
    while(t--){
        int maxlen=0,len=0,pos=0,a[20];
        for(int i=1;i<=8;i++){
            a[i]=0;
            for(int j=1;j<=16;j++){ //数字转换
                int x=getchar()-'0';
                a[i]=a[i]*2+x;
            }
            if(a[i]==0) len++;  //连续0的长度
            else{
                if(len>=maxlen&&len>1){  //更新连续0的最大长度
                    maxlen=len;
                    pos=i-len;
                }
                len=0;
            }
            if(i==8&&len>1){  //如果中间连续零子串较短就选择靠后的
                if(len>maxlen||(len==maxlen&&pos==1)){
                    pos=i-len+1;
                    maxlen=len;
                }
            } 
        }
    //    for(int i=1;i<=8;i++) printf("%d\n",a[i]); 
        printf("Case #%d: ",x-t);
        if(pos==1) printf(":");
        for(int i=1;i<=8;i++){
            if(i==pos) printf(":"),i+=maxlen;
            if(i>8) printf("\n");
            else printf("%x%c",a[i],":\n"[i==8]);//if(i=8) 输出\n else 输出 :
         }
    }
    return 0;
}
/*
题目样例
3 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000010010001101000101011001111000100110101011000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000010010001100000000000000000000000000000000000000000000000001000101011001111000100110101011 */

 后记

这题题目看懂了就好做了,模拟题一般需要看懂题目。

猜你喜欢

转载自www.cnblogs.com/lastonepersonwhohavebitenbycompanies/p/11296224.html