CCF计算机软件能力认证试题练习:201812-3 CIDR合并 【60分】

版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}

猜你喜欢

转载自blog.csdn.net/wingrez/article/details/86601755