IP和DNS都是由32位组成的,每8位决定一个数字0-255,IP地址的数量为2^n,n为IP的二进制后n位,前32-n对于一个网络里的ip都是一样的,DNS直接决定了一个网络里的ip的数量(前32-n位为1,后n位为0)。
有这些知识储备以后,得出最长的公共串即可,只需对二进制数最大和最小的IP进行异或运算,然后统计前面有多少个0,最后把32位转化4个数字即可。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int num[3005];
int ip[4],mask[4];
void dealip(int pos){
int tmp;
tmp=0;
for(int i=pos;i<32;i++){
tmp+=num[0]&(1<<i);
}
for(int i=0;i<4;i++){
for(int j=0;j<8;j++){
if(tmp&(1<<(j+i*8))){
ip[3-i]+=1<<j;
}
}
}
}
void dealmask(int pos){
int tmp=0;
for(int i=pos;i<32;i++){
tmp+=1<<i;
}
for(int i=0;i<4;i++){
for(int j=0;j<8;j++){
if(tmp&(1<<(i*8+j))){
mask[3-i]+=1<<j;
}
}
}
}
int main()
{
int n,a,b,c,d,tmp;
int ans=0,cnt=0,pos;
while(~scanf("%d",&n)){
ans=0;
cnt=0;
memset(ip,0,sizeof(ip));
memset(mask,0,sizeof(mask));
memset(num,0,sizeof(num));
for(int i=0;i<n;i++){
scanf("%d.%d.%d.%d",&a,&b,&c,&d);
num[i]=(a<<24)|(b<<16)|(c<<8)|d;
}
sort(num,num+n);
ans=num[0]^num[n-1];
for(int i=31;i>=0;i--){
tmp=1<<i;
if(!(ans&tmp)) cnt++;
else break;
}
pos=32-cnt;
dealip(pos);
dealmask(pos);
for(int i=0;i<4;i++){
printf("%d",ip[i]);
if(i==3) printf("\n");
else printf(".");
}
for(int i=0;i<4;i++){
printf("%d",mask[i]);
if(i==3) printf("\n");
else printf(".");
}
}
return 0;
}