//读懂题意很重要..........
//substr(pos, n)//从某一位置开始截取长度为n的串.....
//++要想好怎么用 迭代器也要分配好....不然怎么都不出来结果...
/*
思路:读入字符串,将字符串的/后的len,以及转化为标准形式的二进制串str 共同存在结构体里,
按照先str,在len的形式从小到大排序;然后将其进行比较,即是否包含,不包含则进行合并,
删除能合并的不能合并的则保留
2
1.1.1.1/2
1.2.1.1/2
1.1.1.1/2
2
1.1.1.1/2
1.0
1.0.0.0/16
1.1.1.1/2
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<list>
#include<algorithm>
using namespace std;
const int N = 1e5+5;
struct Node {
int len;
string str;
bool operator <(const Node &a)const {
return str==a.str?(len<a.len):(str<a.str);
}
};
list<Node> S;
int ToInt(string s) {
int t=0;
for(int i=0; s[i]; i++) {
t *= 10;
t += (s[i]-'0');
}
return t;
}
void StringtoBit(string &s, int tmp) {
int n=7;
while(n>=0) {
s[n--] = tmp%2+'0';
tmp /= 2;
}
}
int BittoString(string s) {
int tmp = 0;
for(int i=0; i<=7; i++) {
tmp *= 2;
tmp += (s[i]-'0');
}
return tmp;
}
void ToStandard(string s) {
Node temp;
string str(32, '0'), tmp;
vector<string> v;
string flag=".";
int pre = 0, position=0, cnt = 0;
while((position=s.find(flag,position))!=string::npos) {
tmp = s.substr(pre, position-pre);
v.push_back(tmp);
position++;
pre = position;
}
if(s.find('/')!= string::npos) {
position = s.find('/');
tmp = s.substr(pre, position-pre);
v.push_back(tmp);
tmp = s.substr(position+1);
temp.len = ToInt(tmp);
} else if(v.size() == 0) {//没有. /
v.push_back(s);
temp.len = 8;
} else{
tmp = s.substr(pre);
v.push_back(tmp) ;
temp.len = (v.size()*8);//没有/
}
int pos=0;
for(int i=0, j=0; i<v.size(); i++) {
tmp = v[i];
int tn = ToInt(tmp);
int n=7;
string newt = "";
while(n>=0) {
newt += tn%2+'0';
tn /= 2;
n--;
}
for(int k=7; k>=0; k--) {
str[j++] = newt[k];
if(tmp[k] !='0') pos = j;
}
}
temp.str = str;
S.push_back(temp);
}
int Subset(Node a, Node b) {
string s1 = a.str, s2 = b.str;
int len = a.len;
for(int i=0; i<len; i++) {
if(s1[i] != s2[i]) {
return i;
}
}
return len;
}
void print(string s,int len) {
string s1=s.substr(0,8);
string s2=s.substr(8,8);
string s3=s.substr(16,8);
string s4=s.substr(24,8);
cout<<BittoString(s1)<<"."<<BittoString(s2)<<"."<<BittoString(s3)<<"."<<BittoString(s4)<<"/"<<len<<endl;
}
int main() {
ios::sync_with_stdio(false);
int T;
cin >> T;
string tmp;
while(T--) {
cin >> tmp;
ToStandard(tmp);
}
S.sort();
for(list<Node>::iterator it1=S.begin(); it1 != S.end(); ) {//迭代器可能有问题
list<Node>::iterator it2=it1;
it2++;
if(it2 == S.end()) break;
Node ttt = *it1, ttt2 = *it2;
int tttt = Subset(ttt, ttt2);
if(tttt == ttt.len) { //是子集
it2 = S.erase(it2);
} else if(tttt == ttt.len-1 && ttt.len == ttt2.len) { //同级合并
S.erase(it2);
ttt.len--;
*it1 = ttt;
if(it1 != S.begin()) {
it1--;
}
} else {
it1++;//向后继续判断
}
}
for(list<Node>::iterator cur=S.begin(); cur!=S.end(); cur++)
print((*cur).str, (*cur).len);
return 0;
}
//调试版
/*
思路:读入字符串,将字符串的/后的len,以及转化为标准形式的二进制串str 共同存在结构体里,
按照先str,在len的形式从小到大排序;然后将其进行比较,即是否包含,不包含则进行合并,
删除能合并的不能合并的则保留
2
1.1.1.1/2
1.2.1.1/2
1.1.1.1/2
2
1.1.1.1/2
1.0
1.0.0.0/16
1.1.1.1/2
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<list>
#include<algorithm>
using namespace std;
const int N = 1e5+5;
struct Node {
int len;
string str;
bool operator <(const Node &a)const {
return str==a.str?(len<a.len):(str<a.str);
}
};
list<Node> S;
int ToInt(string s) {
int t=0;
for(int i=0; s[i]; i++) {
t *= 10;
t += (s[i]-'0');
}
// sprintf(t, "%s", s);
return t;
}
void StringtoBit(string &s, int tmp) {
int n=7;
while(n>=0) {
s[n--] = tmp%2+'0';
tmp /= 2;
}
// cout << s << endl;
}
int BittoString(string s) {
int tmp = 0;
for(int i=0; i<=7; i++) {
tmp *= 2;
tmp += (s[i]-'0');
}
return tmp;
}
void ToStandard(string s) {
Node temp;
string str(32, '0'), tmp;
// cout << str << endl << s << endl;
vector<string> v;
//查找s 中flag 出现的所有位置。
string flag=".";
int pre = 0, position=0, cnt = 0;
while((position=s.find(flag,position))!=string::npos) {
// cout<<"position : "<<position<<endl;
tmp = s.substr(pre, position-pre);
v.push_back(tmp);
// cout << pre << "-" << position << "=" << tmp << endl;
position++;
pre = position;
}
if(s.find('/')!= string::npos) {
position = s.find('/');
tmp = s.substr(pre, position-pre);
// cout << pre << "-" << position << "=" << tmp << endl;
v.push_back(tmp);
// cout << tmp << ":" << ToInt(tmp) << endl;
tmp = s.substr(position+1);
temp.len = ToInt(tmp);
} else if(v.size() == 0) {//没有. /
// cout << s << endl;
v.push_back(s);
temp.len = 8;
} else{
tmp = s.substr(pre);
v.push_back(tmp) ;
temp.len = (v.size()*8);//没有/
}
int pos=0;
// cout << v.size() << endl;
for(int i=0, j=0; i<v.size(); i++) {
tmp = v[i];
// cout << tmp << endl;
int tn = ToInt(tmp);
int n=7;
// cout << tn << endl;
string newt = "";
while(n>=0) {
newt += tn%2+'0';
tn /= 2;
n--;
}
// cout << newt << endl;
for(int k=7; k>=0; k--) {
str[j++] = newt[k];
// cout << str << endl;
if(tmp[k] !='0') pos = j;
}
}
temp.str = str;
/* if(position == string::npos) {
temp.len = pos;
}*/
//cout << temp.str << "/" << temp.len << endl;
S.push_back(temp);
}
int Subset(Node a, Node b) {
string s1 = a.str, s2 = b.str;
int len = a.len;
for(int i=0; i<len; i++) {
if(s1[i] != s2[i]) {
// cout << i << endl;
return i;
}
}
// cout << len << endl;
return len;
}
void print(string s,int len) {
string s1=s.substr(0,8);
string s2=s.substr(8,8);
string s3=s.substr(16,8);
string s4=s.substr(24,8);
// cout<<s1 <<"."<<s2<<"."<<s3<<"."<<s4<<"/"<<len<<endl;//标准形式
cout<<BittoString(s1)<<"."<<BittoString(s2)<<"."<<BittoString(s3)<<"."<<BittoString(s4)<<"/"<<len<<endl;
}
int main() {
ios::sync_with_stdio(false);
int T;
cin >> T;
string tmp;
while(T--) {
cin >> tmp;
ToStandard(tmp);
}
S.sort();
//cout << S.size() << endl;
for(list<Node>::iterator it1=S.begin(); it1 != S.end(); ) {//迭代器可能有问题
list<Node>::iterator it2=it1;
it2++;
if(it2 == S.end()) break;
Node ttt = *it1, ttt2 = *it2;
int tttt = Subset(ttt, ttt2);
//cout << tttt<<" " << ttt.len << "s" << ttt2.len << endl;
if(tttt == ttt.len) { //是子集
// cout << "子集关系" << endl;
it2 = S.erase(it2);
// it2 = it1++;
} else if(tttt == ttt.len-1 && ttt.len == ttt2.len) { //同级合并
//cout << "同级合并" << endl;
S.erase(it2);
// it2 = it1++;
// cout << (*it1).str<< endl;
ttt.len--;
*it1 = ttt;
//还需将其和前面进行比较看是否能同级合并
if(it1 != S.begin()) {
// it2 = it1;
it1--;
}
} else {
//cout << "都不是" << endl;
it1++;//向后继续判断
// it2++;
}
}
for(list<Node>::iterator cur=S.begin(); cur!=S.end(); cur++)
print((*cur).str, (*cur).len);
return 0;
}