//100分 93ms
#include<stdio.h>//CCF上stdio.h比cstdio快!!!
#include<string.h>
#include<algorithm>
typedef unsigned int UI;
const int N=1e5+5;
struct IP{UI val,a[5];}ip[N];//a[0]~a[3]表示IP地址,a[4]表示题目中的len
//val表示IP地址的十进制形式(主要作用:IP前缀能表示的数值范围)
char str[33];int n;
void dealStr(int id){//字符串点分数字,转换成标准型
scanf("%s",str);
int cnt(0),pn(0),xn(0),len=strlen(str);//pn点的数量,sn斜杠的数量
for(int i=0;i<len;i++){
if(str[i]=='.') pn++;else
if(str[i]=='/') xn++;
}
for(int i=0;i<5;i++) ip[id].a[i]=0;
char *p1=str,*p2,tmp[6];
for(int i=0;i<pn;i++){
p2=strchr(p1,'.');
strncpy(tmp,p1,p2-p1);//strncpy复制从p1中p2-p1长度的字符串到tmp中
tmp[p2-p1]=0;
ip[id].a[cnt++]=atoi(tmp);
p1=p2+1;
}
if(xn){
p2=strchr(p1,'/');//strchr从p1中查找‘/’第一次出现的位置
strncpy(tmp,p1,p2-p1);
tmp[p2-p1]=0;
ip[id].a[cnt++]=atoi(tmp);//atoi 字符串转数字
p1=p2+1;
strcpy(tmp,p1);
ip[id].a[4]=atoi(tmp);
}
else{
strcpy(tmp,p1);
ip[id].a[cnt++]=atoi(tmp);
ip[id].a[4]=cnt*8;
}
ip[id].val=0;//计算ip十进制值
for(int i=0;i<4;i++) ip[id].val+=ip[id].a[i]<<8*(3-i);
}
inline bool cmp(const IP &ip1, const IP &ip2){
for(int i=0;i<5;i++) if(ip1.a[i]!=ip2.a[i]) return ip1.a[i]<ip2.a[i];
return 0;
}
inline void range(IP &ip0,UI &l,UI &r){//计算IP前缀能表示的数值范围
UI len=32-ip0.a[4];
l=ip0.val>>len<<len;
r=ip0.val|((1<<len)-1);
}
void union1(){//从小到大合并
int p=0;
UI la,lb,ra,rb;
for(int i=1;i<n;i++){
range(ip[p],la,ra);
range(ip[i],lb,rb);
if(la>lb||rb>ra) ip[++p]=ip[i];
}
n=p+1;
}
inline bool judgeUnion(IP &ip1,IP &ip2,IP &res){//判断同级能否合并
if(ip1.a[4]!=ip2.a[4]||ip1.a[4]<1) return 0;
res=ip1;res.a[4]--;
UI la,lb,lc,ra,rb,rc;
range(ip1,la,ra);
range(ip2,lb,rb);
range(res,lc,rc);
if(la==lc&&rb==rc&&lb<=ra+1) return 1;
return 0;
}
void union2(){
int p=0;IP res;
for(int i=1;i<n;i++){
if(judgeUnion(ip[p],ip[i],res)){
ip[p]=res;
while(p>0&&judgeUnion(ip[p-1],ip[p],res)) ip[--p]=res;
}
else{
ip[++p]=ip[i];
}
}
n=p+1;
}
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++) dealStr(i);
std::sort(ip,ip+n,cmp);
union1();
union2();
for(int i=0;i<n;i++) printf("%u.%u.%u.%u/%u
",ip[i].a[0],ip[i].a[1],ip[i].a[2],ip[i].a[3],ip[i].a[4]);
return 0;
}

1 #include <bits/stdc++.h>
2
3 using namespace std;
4
5 const int maxn = 1e5 + 5;
6
7 struct node {
8 int ip[4] , len , ip4[33];
9 unsigned int d;
10 node(string s) {
11 bool flag = 0;
12 int cnt = 0;
13 d = len = 0;
14 memset(ip,0,sizeof(ip));
15 for(int i = 0 ; i < s.length() ; i++) {
16 if(s[i] == '.')continue;
17 else if(s[i] == '/') {
18 flag = 1;continue;
19 }
20 else {
21 int t = 0;
22 while(isdigit(s[i])) {
23 t = t * 10 + s[i] - '0';
24 i++;
25 }
26 i--;
27 if(!flag)ip[cnt++] = t;
28 else len = t;
29 }
30 }
31 if(!len)len = cnt * 8;
32 cnt = 7;
33 for(int i = 0 ; i < 4 ; i++) {
34 d = d * 256 + ip[i];
35 int t = ip[i];
36 for(int j = cnt ; j >= cnt - 7 ; j--) {
37 ip4[j] = t % 2;
38 t /= 2;
39 }
40 cnt += 8;
41 }
42 }
43 node(){}
44 bool operator < (const node b) const {
45 return d < b.d || (d == b.d && len < b.len);
46 }
47 };
48
49 node a[maxn];
50 list<node> ans;
51 bool vis[maxn];
52
53 bool judge(node b , node c) {
54 if(c.len < b.len)return false;
55 for(int i = 0 ; i < b.len ; i++) {
56 if(b.ip4[i] != c.ip4[i]) {
57 return false;
58 }
59 }
60 return true;
61 }
62
63 bool judge1(node b , node c) {
64 if(c.len != b.len || c.len == 0)return false;
65 for(int i = 0 ; i < b.len - 1 ; i++) {
66 if(b.ip4[i] != c.ip4[i])return false;
67 }
68 int len = b.len - 1;
69 if(b.ip4[len] != c.ip4[len]) return true;
70 else return false;
71 }
72
73 int main() {
74 int n;
75 ios::sync_with_stdio(0);
76 cin.tie(0);cout.tie(0);
77 cin >> n;
78 for(int i = 0 ; i < n ; i++) {
79 string s;
80 cin >> s;
81 a[i] = node(s);
82 }
83 sort(a , a + n);
84 for(int i = 0 ; i < n ; ) {
85 int p = i;
86 i++;
87 while(i < n && !vis[i]) {
88 if(judge(a[p] , a[i])) {
89 vis[i] = 1;
90 i++;
91 }
92 else break;
93 }
94 }
95 for(int i = 0 ; i < n ; i++) {
96 if(!vis[i])ans.push_back(a[i]);
97 }
98 for(auto t = ans.begin() ; t != ans.end() ; t++) {
99 auto t1 = t;
100 t1++;
101 while(t1 != ans.end() ) {
102 if(judge1(*t , *t1)) {
103 t -> len = t -> len - 1;
104 ans.erase(t1);
105 if(t != ans.begin())t--;
106 t1 = t; t1++;
107 }
108 else break;
109 }
110 }
111 for(auto t = ans.begin() ; t != ans.end() ; t++) {
112 cout << t -> ip[0] << "."<< t -> ip[1] << "." << t -> ip[2] << "." << t -> ip[3] << "/" << t -> len<< "
";
113 }
114 return 0;
115 }
网上list版代码