Z 企业有各种各样的机器人。为了控制所有机器人,操作员 Tom 造了一个“万能遥控器”。只要向遥控器输入一个机器人的 IP 地址,就能遥控这个机器人。可是机器人实在太多,以至于使用 IPv4 协议都不能够唯一地标记每一个机器人。Tom 听说 Ipv6 协议拥有近无穷个地址,于是他就想用 IPv6 协议为机器人设定 IP 地址。
不过,完整的 IPv6 地址很长(有39个字符),手工输入很费时间,所以 IPv6 有一套简化的机制。
IPv6 的地址定义如下:
IPv6 的地址有 128 位,以 16 位为一分组,每个 16位 分组写成 4 个十六进制数,中间用冒号分割,称为冒号分十六进制格式。
例如:21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A 是一个完整 IPv6 地址。
IPv6 地址中每个 16 位分组中的前导零位可以去除做简化表示,但每个分组必须至少保留一位数字。如上例中的地址,去除前导零位后可写成:
21DA:D3:0:2F3B:2AA:FF:FE28:9C5A
某些地址中可能包含很长的零序列,为进一步简化表示法,还可以将冒号十六进制格式中相邻分组的连续零位合并,用双冒号“::”表示。“::”符号在一个地址中只能出现一次,该符号也能用来压缩地址中前部和尾部相邻的连续零位。
注意:(一个单独的 0 分组不能使用“::”省略。
例如地址:
样例一:1080:0:0:0:8:800:200C:417A 可表示为压缩格式 1080::8:800:200C:417A
样例二:0:0:0:0:0:0:0:1 可表示为压缩格式 ::1
样例三:0:0:0:0:0:0:0:0 可表示为压缩格式 ::
现在,Tom 给了你一些 IPv6 地址,请你编写程序,把它们转换成完整的地址。
第一行为一个正整数 N ,表示将有 N 个 IP 地址。
接下来有 n 行,每行一个非空字符串,表示一个地址。输入只包含数字、大写字母、冒号(:)和换行符,输入每行不超过 39 个字符。
输出一共 N 行,每行一个字符串。对每个输入的字符串,如果符合 IPv6 标准,则输出其对应的完整的 IPv6 地址,否则输出“INVALID”。
【数据范围】
对100%的数据,保证:1≤N≤35
个人说明:
此题比较坑,有大量情况需要讨论,试了N次才AC................................................
而且最后才发现compile error的原因:
忘打这个了..................
#include
#include
正解如下:
版本1(原创)(复制上来有点错位。。):
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int n,len,tot1,tot2,kong,ong,index,num;
char ip[40],out[40];
bool dd,hh,more;
int main()
{
freopen("ipv6.in","r",stdin);
freopen("ipv6.out","w",stdout);
cin>>n;
while(n>0)
{
memset(ip,0,sizeof(ip));
scanf("%s",ip);
len=strlen(ip);
tot1=0,tot2=0;
kong=0,index=0,ong=0;
dd=hh=more=false;
for(int i=0;i4) hh=true;
if(ip[i]>'F') more=true;
if(ip[i]==':') tot2++,tot1=0,kong++;
if(tot2>2) hh=true;
if(tot2==2)
{
if(dd==true) more=true;
else dd=true,index=kong;
}
}
if((ip[0]==':'&&ip[1]!=':')||(ip[len-1]==':'&&ip[len-2]!=':')||ong>8) more=true;
if((ong<8&&dd==false)||(ong>=7&&dd==true)) more=true;
if(kong>7&&dd==true) more=true;
tot1=0,tot2=0,num=0;
if(hh==false&&more==false)
{
for(int i=0;i=1;j--) cout<=1;j--) cout<=1;j--) cout<=1;j--) cout<
版本2(teacher的题解)(<- _<- 尽管并不能AC。。):
#include
#include
#include
#include
#include
#include
#include
using namespace std;
char s[100],a[100];
int main()
{
freopen("ipv6.in","r",stdin);
freopen("ipv6.out","w",stdout);
int n;
scanf("%d\n",&n);
for(int ii=1;ii<=n;ii++)
{
memset(s,'0',sizeof(s));
memset(a,'0',sizeof(a));
char c;
int p1=0,p2=0,p3=0,p4=0,k=0,point=0;
while((c=getchar())!=EOF && c!='\n')
{
s[++k]=c;
if(c==':') {
p1=0; p2++;
}
else p1++;
if(p1>4 || p2>7) p4=1;
if(c==':' && s[k-1]==':') {
p3++;point=k;
}
if(p3>1) p4=1;
}
if(!p3 && p2<7) p4=1;
if(p3 && p2==7 && point!=2 && point!=k) p4=1;
for(int i=1;i<=k;i++)
a[i]=s[k-i+1];
if(p4)
{
printf("INVALID\n");continue;
}
int q=0;
p1=0;
for(int i=1;i<=k;i++)
{
s[++q]=a[i];
p1++;
if(a[i]==':')
{
q--;
while(p1<5)
{
s[++q]='0';
p1++;
}
s[++q]=':';
p1=0;
if(a[i+1]==':')
{
while(p2<=7)
{
for(int j=1;j<=4;j++)
s[++q]='0';
s[++q]=':';
p2++;
}
q--;
p1=4;
}
}
}
for(int i=39;i>=1;i--) printf("%c",s[i]);
cout<
版本3(某位同学的,因其太有个性。。。):
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int n,len,top,next[25],figure[25];
char str[25];
void move()
{
for(int i=len;i>=1;i--)
str[i]=str[i-1];
return;
}
int main()
{
freopen("ipv6.in","r",stdin);
freopen("ipv6.out","w",stdout);
scanf("%d",&n);
for(int p=1;p<=n;p++)
{
scanf("%s",str);
len=strlen(str);
if(str[1]!=':'&&str[0]==':')
{
cout<<"INVALID"<=3)
{
judge=false;
break;
}
if(check==2)
{
repeat++;
if(repeat>=2)
{
judge=false;
break;
}
}
}
}
if(top>8)
judge=false;
if(repeat==0&&top<8)
judge=false;
if(repeat==1&&top>=7)
judge=false;
if(!judge)
{
cout<<"INVALID"<4)
{
judge=true;
break;
}
}
if(judge)
{
cout<<"INVALID"<=7)
{
judge=true;
break;
}
}
if(next[i]-(next[i-1]+figure[i-1]-1)>3)
{
judge=true;
break;
}
}
if(judge)
{
cout<<"INVALID"<