2019牛客多校训练 第六场 B-Shorten IPv6 Address
题目
https://ac.nowcoder.com/acm/contest/886/B
题意
给你长度为128的01字符串s,让你把他转换成16进制的字符串。字符串s分为8组,长度为16分为一组,每组都对应转换为16进制的字符串。
为了使16进制字符串尽可能的短,前导0可以忽略省略,为了使每组都分开要求用“:”将两组分开。如果有两组或以上的0,可以用“::”替代,并且只能替换一串连续的0。
比如:
‘0000:0000:0123:4567:89ab:0000:0000:0000’
可以变成0:0:123:4567:89ab:0:0:0
两组或以上的0用“::”替代,变成0:0:123:4567:89ab::
题解
最方便的可以把2进制转化为10进制,判断连续0的个数,将最多连续0的下标记录下来,输出的时候把他们换成“::”就可以了。但是要注意,0相同的情况下将中间的0换成“::”能使字符串更加短。把十进制以16进制的形式输出也很简单,用%x就可以了。
QAQ题目看起来很简单,但是我还是wa了很多发,真的哭了。。。
接下来就是让我自闭好几个小时的AC代码了
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
int turnn(char a[])
{
int sum=0;
for(int i=0; i<16; i++)
{
sum=sum*2+a[i]-'0';
}
return sum;
}
int a[10];
char b[20];
int main()
{
int n;
cin>>n;
{
for(int k=0; k<n; k++)
{
memset(a,-1,sizeof(a));
for(int j=1; j<=8; j++)
{
scanf("%16s",b);
a[j]=turnn(b);
}
int sum[10],index=0;
memset(sum,0,sizeof(sum));
for(int i=8; i>=1; i--)
{
if(a[i] == 0)
{
sum[i] = sum[i+1] + 1;
}
if(sum[i] > sum[index])
{
index = i;
}
else if(sum[i] == sum[index])
{
if(sum[index]+index-1 == 8&&i!=1)
index = i;
}
}
printf("Case #%d: ",k+1);
if(sum[index] < 2)
{
for(int i=1; i<=8; i++)
{
printf("%x",a[i]);
if(i<=7)
printf(":");
}
}
else
{
for(int i=1; i<=8; i++)
{
if(i==index)
{
if(index != 1)
printf(":");
else
printf("::");
i = sum[index]+index-1;
continue;
}
printf("%x",a[i]);
if(i<=7)
printf(":");
}
}
cout<<endl;
}
}
}