试题编号: | 201812-3 |
试题名称: | CIDR合并 |
时间限制: | 1.0s |
内存限制: | 512.0MB |
问题描述: | |
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
typedef struct Node{
int len;//len要写在long long的前面
int ip[4];//ip 0,1,2,3 表示IP的1,2,3,4段
long long val;//IP的十进制数
}Node;
int getNum(string s){//字符串转化为数字
int sum=0;
for(int i=0;i<s.size();i++){
sum+=(s[i]-'0')*pow(10,s.size()-i-1);
}
return sum;
}
Node node[100105];int n;
int deal_input(int no,string s){//解析IP
int i=0,dotNum=0;
while(1){
if(i>=s.size())break;
if(s[i]=='/')break;
if(s[i]=='.')dotNum++;
i++;
}
string ip;int len;
ip=s.substr(0,i);
if(dotNum==0){
ip+=".0.0.0";
}else if(dotNum==1){
ip+=".0.0";
}else if(dotNum==2){
ip+=".0";
}
if(i>=s.size()){
if(dotNum==0)len=8;
else if(dotNum==1)len=16;
else if(dotNum==2)len=24;
else len=32;
}else len=getNum(s.substr(i+1,s.size()-i-1));
Node temp;int a=0,b=0,c=3,x,t=0;
temp.len=len;
while(b<ip.size()){
if(ip[b]=='.'){
x=getNum(ip.substr(a,b-a));
temp.ip[t++]=x;
temp.val+=x*pow(256,c--);
a=b+1;
}b++;
}
x=getNum(ip.substr(a,b-a));
temp.ip[t++]=x;
temp.val+=x*pow(256,c--);
node[no]=temp;
}
bool cmp(Node a,Node b){//排序
if(a.val!=b.val)return a.val<b.val;
return a.len<b.len;
}
int deal_del_1(){//第一次消除,消除子集 ,消除次数较多,不能采用循环中退步的方式
int p=0;
for(int i=1;i<n;i++){
Node first=node[p],second=node[i];
if(!((first.val>>(32-first.len))==second.val>>(32-first.len))){
node[++p]=node[i];//注意消除算法,其中这次消除占大部分时间,消除算法很重要
}
}
n=p+1;
}
bool judge_del(Node ip1, Node ip2, Node &temp){ //判断同级能否合并
if(ip1.len!=ip2.len) return false;
temp=ip1; temp.len-=1;
if(temp.val>>(32-temp.len)<<(32-temp.len)==ip2.val>>(32-ip2.len+1)<<(32-ip2.len+1)) return true;
return false;
}
int deal_del_2(){//第二次消除 ,所占时间较少,可采用循环中退步的消除方式
int p=0;
Node temp;
for(int i=1;i<n;i++){
if(judge_del(node[p],node[i],temp)){
node[p]=temp;
while(p>0 && judge_del(node[p-1], node[p], temp)) node[--p]=temp;
}
else node[++p]=node[i];
}
n=p+1;
}
int main(){
string s;
cin>>n;
for(int i=0;i<n;i++){
cin>>s;
deal_input(i,s);
}
sort(node,node+n,cmp);
deal_del_1();
deal_del_2();
for(int i=0;i<n;i++){
cout<<node[i].ip[0]<<"."<<node[i].ip[1]<<"."<<node[i].ip[2]<<"."<<node[i].ip[3]<<"/"<<node[i].len<<endl;
}
}
更多相关CCF的试题解答,请点击>>CCF历年认证考试解答