//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\n",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<< "\n"; 113 } 114 return 0; 115 }