题目链接:https://ac.nowcoder.com/acm/contest/886/B
题意:
您将获得一个IPv6地址,该地址是128位二进制字符串。请根据以下规则确定其最短的表示:
以十六进制表示形式表示地址,并使用冒号':'分割每四个十六进制数字。每四个数字称为一个字段。例如,'0000:0000:0123:4567:89ab:0000:0000:0000'
可以省略字段中的前导零。例如,上述IPv6地址可以缩短为 '0:0:123:4567:89ab:0:0:0'
由至少两个字段组成的连续零字段(靠近它们的冒号)可以用双冒号 '::' 替换。此外,地址中不能使用多个双冒号。
例如,上面的IPv6地址可以缩短为 '0:0:123:4567:89ab ::' 或 ':: 123:4567:89ab:0:0:0',但不能缩写为 ':: 123:4567: 89ab ::‘
如果有多个相同长度的最短格式,请使用字典序(将缩短的IPv6地址视为字符串)最小的一个
思路:
模拟处理字符串
个人感觉python比较好处理字符串,所以比赛的时候用python写的,python用的不多写得不好看,有python大佬的话就将就一下叭
先将二进制转为十六进制,并加入 “ : ”
然后将所有前导零去掉
寻找数目最多的相邻的 “ :0: ” ,将其变为 “ :: ”
注意:在可替换的 “ :0: ” 数目相同的情况下,换中间是比换最前和最后的优先级高的, 因为能多去掉一个冒号
(WA了无数发)
t=int(input())
for i in range(t):
s=input()
l=len(s)
k=0; m=1; x=[]; y=['','','','','','','','','','','a','b','c','d','e','f']
for j in range(l-1,-1,-1):
k+=int(s[j])*m; m=m*2
if j%4==0:
x.append(y[k])
if j%16==0:
x.append(':')
k=0; m=1
x.reverse()
m=0; l=len(x)
for j in range(l):
if m==l:
break
if x[j]==':' and x[j+1]=='':
del x[j+1]
j-=1; m+=1
m+=1
m=0; l=len(x)
for j in range(l):
if m==l:
break
if x[j]==':' and x[j+1]=='':
del x[j+1]
j-=1; m+=1
m+=1
m=0; l=len(x)
for j in range(l):
if m==l:
break
if x[j]==':' and x[j+1]=='':
del x[j+1]
j-=1; m+=1
m+=1
x.append(':')
l=len(x); r=1; sum=0; ans=0; p=0
for j in range(l):
if x[j]==':':
if j!=l-1 and r==0 and x[j+1]=='':
sum+=1
else:
if sum>ans:
p=j-2*(sum+1); ans=sum; sum=0; r=1
if sum==ans and j!=l-1:
p=j-2*(sum+1); ans=sum; sum=0; r=1
if j==l-1 and sum>=ans:
if sum>ans or (sum==ans and p==0):
p=j-2*(sum+1); ans=sum; sum=0; r=1
if j!=l-1 and x[j+1]!='':
r=1
else:
r=0
if ans!=0:
if p+ans*2+2==len(x)-1:
f=1
else:
f=0
for j in range(ans*2+2):
del x[p]
if f==1:
if p==0:
x.insert(p, ':')
else:
x.insert(p, ':')
del x[0]
if f==0:
if p==0:
x.insert(p, ':')
del x[len(x) - 1]
else:
x.insert(p, ':')
del x[0]; del x[len(x)-1]
else:
del x[0]; del x[len(x) - 1]
print("Case #"+str(i+1)+": "+"".join(x))