ccf 201812-3 CIDR合并(100分)

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
提交后得100分的C++程序如下:

#include<iostream>
#include<string>
#include<cstring>
#include<vector>
#include<algorithm>
#include<list>
using namespace std;
int pow[]={128,64,32,16,8,4,2,1};
struct ip
{
	string adress,adress1; 
	int len;
	bool operator<(const ip &s) const
	{
		if(adress1==s.adress1) return len<s.len;
		else return adress1<s.adress1;
	}
};
bool check(string p,string q,int len)
{
	if(len>p.length()||len>q.length()) return false;
 	for(int i=0;i<len;i++)
 	  if(p[i]!=q[i])
 	    return false;
 	return true;
} 
int main()
{
  	list<ip> v;
  	int n;
  	cin>>n;
  	while(n--)
  	{
  		ip value;
  		string str;
  		cin>>str;
  		int pos=str.find('/'); //先处理省略长度型 
  		if(pos==-1)
  		{
  			value.adress=str;
  			value.len=-1;  //代表暂时没有长度 
		  }
		  else
		  {
		  	string sum=str.substr(pos+1);
		  	int len=0;
		  	for(int i=0;i<(int)sum.length();i++)  //把前缀长度由字符串类型转化为int类型 
		  	{
		  		len=len*10+(sum[i]-'0');
			  }
			  value.adress=str.substr(0,pos);
			  if(sum!="") value.len=len;
			  else value.len=-1;
		  }
		  int point=0;//记录'.'的总数 
		  for(int i=0;i<(int)value.adress.size();i++)
		  {
		  	if(value.adress[i]=='.') point++; 
		  }
		  for(int i=0;i<3-point;i++)
		  {
		  	value.adress+=".0";
		  }
		  if(value.len==-1)
		  {
			 value.len=(point+1)*8;
		  }
		  int count=0,figure[4];//存储十进制整数 
		  string  digit[4],b;//暂时存储 
		  for(int i=0;i<(int)value.adress.size();i++)
		  {
		  	if(value.adress[i]=='.') 
		  	{
		  		digit[count]=b;
		  		count++,b="";
			  }
		  	else
		  	{
		  		b+=value.adress[i];
			  }
		  }
		  digit[count]=b; //结束要像遇到'.'那样处理
		  for(int i=0;i<4;i++)
		  {
		  	int len=0;
		    for(int j=0;j<(int)digit[i].length();j++)  //把字符串类型转化为int类型 
		  	{
		  		len=len*10+(digit[i][j]-'0');
			  }
			  figure[i]=len;
		   }		 
		   for(int i=0;i<4;i++) //128 64 32 16 8 4 2 1
		   {                     
		   	 for(int j=0;j<8;j++) 
		   	 {
		   	 	if(figure[i]>=pow[j])
		   	 	{
		   	 		figure[i]-=pow[j];
		   	 		value.adress1+="1";
					}
					else value.adress1+="0";
				}
		   }
		  v.push_back(value);
	  }
	  v.sort();
	 for(list<ip>::iterator cur=v.begin();cur!=v.end();)//遍历列表 
	{
		list<ip>::iterator next=cur;
		next++; 
		if(next==v.end())
		  break;   
		ip p1=*cur; 
		ip p2=*next;
		if(check(p1.adress1,p2.adress1,p1.len))
		{
			v.erase(next);
		}
		else
		  cur++;
	}	
	for(list<ip>::iterator cur=v.begin();cur!=v.end();)//遍历列表 
	{
		list<ip>::iterator next=cur;
		next++;
		if(next==v.end())
		  break; 	  
		ip p1=*cur;
		ip p2=*next;
		if(p1.len==p2.len&&p1.len>0&&p1.adress1[p1.len-1]=='0')
		{
			ip tmp=p1;
			tmp.len--;
			if(check(tmp.adress1,p2.adress1,tmp.len))
		    {
			  v.erase(next);
			  *(cur)=tmp;
			  if(cur!=v.begin()) 
			    cur--;
		    }
		    else
		      cur++;
		}
		else
		  cur++; 
	}
	 for(list<ip>::iterator cur=v.begin();cur!=v.end();cur++)
	 {
	 	cout<<(*cur).adress<<"/"<<(*cur).len<<endl;
	 }
}

猜你喜欢

转载自blog.csdn.net/jinduo16/article/details/86713447