试题编号: 201812-3
试题名称: CIDR合并
时间限制: 1.0s
内存限制: 512.0MB
问题描述:
样例输入
2
1
2
样例输出
1.0.0.0/8
2.0.0.0/8
样例输入
2
10/9
10.128/9
样例输出
10.0.0.0/8
样例输入
2
0/1
128/1
样例输出
0.0.0.0/0
本来以为最后一个点会TLE,没想到测试数据这么弱,这都能100分
代码如下(100分):
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
static const int MAXN=100000;
struct Node{
unsigned int num;
int len;
int bit[35];
bool f;
}ip[MAXN+10],newip[MAXN+10];
int cnt=0;
void div(char s[])
{
cnt++;
ip[cnt].len=-1;
ip[cnt].f=true;
int p=0,len=strlen(s);
for(int i=0;i<len;i++)
{
int x=0;
while(i<len && s[i]!='.' && s[i]!='/')
{
x=x*10+s[i]-'0';
i++;
}
ip[cnt].num+=x*pow(256,3-p);
for(int j=p*8+7;j>=p*8;j--)
{
ip[cnt].bit[j]=x%2;
x/=2;
}
if(s[i]=='/')
{
int y=0;
while(++i<len)
y=y*10+s[i]-'0';
ip[cnt].len=y;
return;
}
p++;
}
return;
}
bool cmp(Node P,Node Q)
{
if(P.num==Q.num)
return P.len<Q.len;
return P.num<Q.num;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0),cout.tie(0);
int n;
char s[20];
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>s;
div(s);
if(ip[cnt].len==-1)
{
int pointnum=0;
for(int j=0;s[j];j++)
if(s[j]=='.')
pointnum+=1;
ip[cnt].len=pointnum*8+8;
}
}
sort(ip+1,ip+n+1,cmp);
int p=1;
newip[1]=ip[1];
for(int i=2;i<=n;i++)
{
for(int j=0;j<newip[p].len;j++)
{
if(ip[i].bit[j]==newip[p].bit[j])
continue;
else
{
newip[++p]=ip[i];
break;
}
}
}
while(1)
{
bool flag=false;
int pp;
for(int i=1;i<=p;i++)
if(newip[i].f)
{
pp=i;
break;
}
for(int i=pp+1;i<=p;i++)
{
if(!newip[i].f)
continue;
if(newip[i].len==newip[pp].len)
{
for(int j=0;j<newip[i].len-1;j++)
if(newip[i].bit[j]!=newip[pp].bit[j])
{
pp=i;
break;
}
if(pp!=i)
{
newip[pp].len-=1;
newip[i].f=false;
flag=true;
}
}
else
pp=i;
}
if(!flag)
break;
}
for(int i=1;i<=p;i++)
{
if(!newip[i].f)
continue;
unsigned int a,b,c,d;
a=newip[i].num/(256*256*256); newip[i].num%=256*256*256;
b=newip[i].num/(256*256); newip[i].num%=256*256;
c=newip[i].num/256; newip[i].num%=256;
d=newip[i].num;
cout<<a<<"."<<b<<"."<<c<<"."<<d<<"/"<<newip[i].len<<endl;
}
return 0;
}