试题编号: 201812-3
试题名称: CIDR合并
时间限制: 1.0s
内存限制: 512.0MB
样例输入
2
1
2
样例输出
1.0.0.0/8
2.0.0.0/8
样例输入
2
10/9
10.128/9
样例输出
10.0.0.0/8
样例输入
2
0/1
128/1
样例输出
0.0.0.0/0
90分 运行超时
可能是将点分十进制转换为二进制字符串形式,最后输出的时候再转为int形式的二进制自己写的函数步骤太多的原因
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
struct IP {
string ip;
int len;
};
//将点分十进制转换成标准二进制形式并存入IP结构体
void trans(IP &ip1, string s1) {
int p1=0, p2, l=0, x, s;
string st;
while ((p2 = s1.find('.',p1+1)) >= 0)
{
l = l + 8;
st = s1.substr(p1, p2 - p1);
x = atoi(st.c_str());
s = 128;
while (s > 0)
{
if (x / s == 1)
{
ip1.ip += '1';
x %= s;
}
else
ip1.ip += '0';
s /= 2;
}
p1 = p2+1;
}
l = l + 8;
if ((p2 = s1.find('/', 0)) >= 0)
{
st = s1.substr(p1, p2 - p1);
x = atoi(st.c_str());
s = 128;
while (s > 0)
{
if (x / s == 1)
{
ip1.ip += '1';
x = x%s;
}
else
ip1.ip += '0';
s /= 2;
}
p1 = p2 + 1;
p2 = s1.length();
st = s1.substr(p1, p2 - p1);
ip1.len = stoi(st.c_str());
}
else
{
p2 = s1.length();
st = s1.substr(p1, p2 - p1);
x = atoi(st.c_str());
s = 128;
while (s > 0)
{
if (x / s == 1)
{
ip1.ip += '1';
x = x%s;
}
else
ip1.ip += '0';
s /= 2;
}
ip1.len = l;
}
for (int j = l; j < 32; j++)
{
ip1.ip += '0';
}
}
//对IP进行排序,用sort函数 按ip从小到大排,如果相同再按前缀从大到小排序
int comp(const IP &ip1, const IP &ip2) {
if (ip1.ip == ip2.ip)
return ip1.len < ip2.len;
else
return ip1.ip < ip2.ip;
}
//二进制转十进制
void zhuan(string ss,int &xx){
xx = atoi(ss.c_str());
long long int f = 10000000,s=0,ff=128;
for (int i = 0; i < 8; i++)
{
if (xx / f == 1)
s += ff;
xx = xx%f;
ff /= 2;
f /= 10;
}
xx = s;
}
int main() {
int i, j, n, m, flag, flag1, flag2;
string s;
IP ipv[100001];
cin >> n;
for (i = 0; i < n; i++)
{
cin >> s;
trans(ipv[i], s);
}
sort(ipv, ipv + n , comp); //头文件需注意 还有自定义函数的用法
//从小到大合并
flag = n;
for (i = 0; i < flag-1; i++)
{
flag1 = 0;
for (j = 0; j < ipv[i].len; j++) //按前一个的前缀部分来看都相同 说明后者是前者的子集
{
if (ipv[i].ip[j] != ipv[i + 1].ip[j])
{
flag1 = 1;
break;
}
}
if (flag1 == 0)
{
flag--;
for (j = i+1; j < flag; j++)
ipv[j] = ipv[j + 1];
i--;
}
}
//同级合并
for (i = 0; i < flag - 1; i++)
{
if (ipv[i].len == ipv[i+1].len)
{
flag2 = 0;
for (j = 0; j < ipv[i].len - 1; j++)
{
if (ipv[i].ip[j] != ipv[i + 1].ip[j]) {
flag2 = 1;
break;
}
}
if (flag2 == 0 && ipv[i].ip[ipv[i].len - 1] == '0'&&ipv[i + 1].ip[ipv[i].len - 1] == '1') {
ipv[i].len =ipv[i].len- 1;
for (j = i + 1; j < flag - 1; j++)
ipv[j] = ipv[j + 1];
flag--;
if (i > 0)
i = i - 2;
else
i--;
}
}
}
for (i = 0; i < flag; i++)
{
int p1 = 0;
int p2 = 8, f;
string st;
while (p2 <= 32)
{
st = ipv[i].ip.substr(p1, p2 - p1);
zhuan(st, f);
if (p1 != 0)
cout << ".";
cout << f;
p1 = p2;
p2 += 8;
}
cout <<"/" << ipv[i].len << endl;
}
return 0;
}