版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wingrez/article/details/86601755
CIDR合并
来源:CCF
标签:
参考资料:
相似题目:
题目
输入样例1
2
1
2
输出样例1
1.0.0.0/8
2.0.0.0/8
输入样例2
2
10/9
10.128/9
输出样例2
10.0.0.0/8
输入样例3
2
12
0/1
128/1
输出样例3
0.0.0.0/0
扫描二维码关注公众号,回复: 5078222 查看本文章
解题思路
请直接参考代码。
参考代码
#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
#define MAXN 1000005
using namespace std;
typedef unsigned int UI;
struct IP{
UI a;
UI b;
UI c;
UI d;
int len;
};
bool cmp(IP ip1, IP ip2){
if(ip1.a<ip2.a) return true;
if(ip1.a>ip2.a) return false;
if(ip1.b<ip2.b) return true;
if(ip1.b>ip2.b) return false;
if(ip1.c<ip2.c) return true;
if(ip1.c>ip2.c) return false;
if(ip1.d<ip2.d) return true;
if(ip1.d>ip2.d) return false;
if(ip1.len<ip2.len) return true;
return false;
}
int n;
IP ip[MAXN];
vector<IP> ipv;
void deal_str(int no,char *str){
char tmp[10];
char *p1=strchr(str,'.');
char *p2=strchr(str,'/');
if(p1==NULL){
if(p2==NULL){ // no '.' and no '/'
ip[no].a=atoi(str);
ip[no].len=8;
return;
}
int c=p2-str; // no '.' , has '/'
strncpy(tmp,str,c);
tmp[c]='\0';
ip[no].a=atoi(tmp);
strcpy(tmp,p2+1);
ip[no].len=atoi(tmp);
return;
}
else if(p2==NULL){// has '.', no '/'
int c1=p1-str;
strncpy(tmp,str,c1);
tmp[c1]='\0';
ip[no].a=atoi(tmp);
char *p3=strchr(p1+1,'.');
if(p3==NULL){
strcpy(tmp,p1+1);
ip[no].b=atoi(tmp);
ip[no].len=16;
return;
}
int c2=p3-p1-1;
strncpy(tmp,p1+1,c2);
tmp[c2]='\0';
ip[no].b=atoi(tmp);
char *p4=strchr(p3+1,'.');
if(p4==NULL){
strcpy(tmp,p3+1);
ip[no].c=atoi(tmp);
ip[no].len=24;
return;
}
int c3=p4-p3-1;
strncpy(tmp,p3+1,c3);
tmp[c3]='\0';
ip[no].c=atoi(tmp);
strcpy(tmp,p4+1);
ip[no].d=atoi(tmp);
ip[no].len=32;
return;
}
else{ // has '.' and '/'
int c4=p1-str;
strncpy(tmp,str,c4);
tmp[c4]='\0';
ip[no].a=atoi(tmp);
strcpy(tmp,p2+1);
ip[no].len=atoi(tmp);
char *p3=strchr(p1+1,'.');
if(p3==NULL){
int c5=p2-p1-1;
strncpy(tmp,p1+1,c5);
tmp[c5]='\0';
ip[no].b=atoi(tmp);
return;
}
int c6=p3-p1-1;
strncpy(tmp,p1+1,c6);
tmp[c6]='\0';
ip[no].b=atoi(tmp);
char *p4=strchr(p3+1,'.');
if(p4==NULL){
int c7=p2-p3-1;
strncpy(tmp,p3+1,c7);
tmp[c7]='\0';
ip[no].c=atoi(tmp);
return;
}
int c8=p4-p3-1;
strncpy(tmp,p3+1,c8);
tmp[c8]='\0';
ip[no].c=atoi(tmp);
int c9=p2-p4-1;
strncpy(tmp,p4+1,c9);
tmp[c9]='\0';
ip[no].d=atoi(tmp);
return;
}
return;
}
int main(){
char str[25];
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%s",str);
deal_str(i,str);
}
//for(int i=0;i<n;i++){
// printf("%d.%d.%d.%d/%d\n",ip[i].a,ip[i].b,ip[i].c,ip[i].d,ip[i].len);
//}
sort(ip,ip+n,cmp);
for(int i=0;i<n;i++){
ipv.push_back(ip[i]);
}
vector<IP>::iterator itp=ipv.begin(),
itc=ipv.begin()+1;
while(itp!=ipv.end()-1){
UI add1=((*itp).a<<24) + ((*itp).b<<16) + ((*itp).c<<8) + (*itp).d;
UI add2=((*itc).a<<24) + ((*itc).b<<16) + ((*itc).c<<8) + (*itc).d;
int len=(*itp).len<(*itc).len? (*itp).len : (*itc).len;
add1=add1>>(32-len);
add2=add2>>(32-len);
int flag=1;// 1 is include, 0 is not include
for(int j=0;j<len;j++){
add1=add1>>j;
add2=add2>>j;
if((add1&1)!=(add2&1)){
flag=0;
break;
}
}
if(flag==1){
itc=ipv.erase(itc);
}
else{
itp++;
itc++;
}
}
itp=ipv.begin();
itc=ipv.begin()+1;
while(itp!=ipv.end()-1){
IP ipt=*itp;
ipt.len-=1;
if((*itp).len!=(*itc).len || ipt.len<0){
itp++;
itc++;
continue;
}
UI add1=((*itp).a<<24) + ((*itp).b<<16)+ ((*itp).c<<8) + (*itp).d;
UI add2=((*itc).a<<24) + ((*itc).b<<16)+ ((*itc).c<<8) + (*itc).d;
UI add3=(ipt.a<<24) + (ipt.b<<16) + (ipt.c<<8) + ipt.d;
int len=ipt.len<(*itp).len? ipt.len : (*itp).len;
add1=add1>>(32-len);
UI addt=add3>>(32-len);
int flag=2;// 2 is all include, 1 is only one include, 0 is not include
for(int j=0;j<len;j++){
add1=add1>>j;
addt=addt>>j;
if((add1&1)!=(addt&1)){
flag--;
break;
}
}
len=ipt.len<(*itc).len? ipt.len : (*itc).len;
add2=add2>>(32-len);
addt=add3>>(32-len);
for(int j=0;j<len;j++){
add2=add2>>j;
addt=addt>>j;
if((add2&1)!=(addt&1)){
flag--;
break;
}
}
if(flag==2){
itp=ipv.erase(itp);
itp=ipv.erase(itp);
vector<IP>::iterator itt=ipv.insert(itp,ipt);
if(itt!=ipv.begin()) itp=itt-1;
else itp=itt;
}
else itp++;
itc=itp+1;
}
for(vector<IP>::iterator it=ipv.begin();it!=ipv.end();it++){
printf("%u.%u.%u.%u/%u\n",(*it).a,(*it).b,(*it).c,(*it).d,(*it).len);
}
return 0;
}