CCF认证 201812-3CIDR合并

CCF认证 201812-3CIDR合并题目描述

#include<bits/stdc++.h>
using namespace std; 
struct node
{
	string ip="";
	int length=-1;
	bool operator <(const node &a)const//第一步的合并 
	{
		if(ip!=a.ip)
		    return ip<a.ip;
		return length<a.length;
		
	}
};
list<node>address;
//处理ip地址为统一格式 
int a[8]={1,2,4,8,16,32,64,128};
node tostr(string &ip)
{
	node nd;
	string s="";
	for(int i=0;i<=ip.size();i++)
	{
		if(!isdigit(ip[i])||i==ip.size())
		{
			int k=stoi(s);
			s="";
			for(int j=7;j>=0;j--)
			{
				if(k>=a[j])
				{
					nd.ip+="1";
					k-=a[j];
				}
				else
				{
					nd.ip+="0";
				}
			}
		if(ip[i]=='/')
		{
			nd.length=stoi(ip.substr(i+1));
			//cout<<"1"<<nd.length<<endl;
			break;
		}
	}
		else
		{
			s+=ip[i];
		}
	}
	if(nd.length==-1)
	{
		nd.length=nd.ip.size();
	}
	while(nd.ip.size()<32)
	{
		nd.ip+="0";
	}
	
	//cout<<nd.ip<<" "<<nd.length<<endl;
	return nd;
}
//第二步是否为子集的判断
bool son(node &a,node &b) //判断b是否为a的子集
{
	if(a.length>b.length)
	   return false;
	for(int i=0;i<a.length;i++)
	{
		if(a.ip[i]!=b.ip[i])
		  return false;
	}
	return true;
} 
//进行合并操作
void merge1(list<node>&add)
{
	auto i=add.begin(),j=add.begin();
	for(++j;j!=add.end();)
	{
		if(son(*i,*j))
		{
			j=add.erase(j);
		}
		else
		{
			i++;
			j++;
		}
	}
}
//判断ab两个子集是否可以合并为一个子集
bool union1(node &a,node &b)
{
	if(a.length!=b.length)
	  return false;
	for(int i=0;i<a.length-1;i++)
	{
		if(a.ip[i]!=b.ip[i])
		  return false;
	}
	return a.ip[a.length-1]!=b.ip[a.length-1];
 }
//第二步合并
void merge2(list<node>&add)
{
	auto i=add.begin(),j=add.begin();
	for(++j;j!=add.end();)
	{
		if(union1(*i,*j))
		{
			j=add.erase(j);
			(*i).length--;
	        if(i!=add.begin())
		    {
			i--;
			j--;
		    }
		}
		else
		    {
			i++;
			j++;
		   }
	}
 } 
int main()
{
	int n;
	cin>>n;
	string ip;
	for(int i=0;i<n;i++)
	{
		cin>>ip;
		address.push_back(tostr(ip));
	}
	address.sort();
	//cout<<address.size()<<endl;
	merge1(address);
	merge2(address);
	//遍历进行输出
	//cout<<"123yy"<<endl;
	//cout<<address.size()<<endl;
	for(auto&it:address)
	{
		for(int i=0;i<4;i++)
		{
			int k=0;
			for(int x=0,j=7;j>=0;j--,x++)
			{
				k+=a[j]*((it).ip[i*8+x]-'0');
			}
			cout<<k;
			if(i!=3)
			cout<<".";
		}
		cout<<"/"<<(it).length<<endl;;
	 }
	 cout<<endl;
	  return 0;
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值