|
|
#include <bits/stdc++.h>
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
unsigned i, m, ip[4], ipmax[4], ipmin[4], mask[4];
|
|
|
|
|
|
/**
|
|
|
* 功能:比较器,四位,某一位有大小,就比如成功,小返回-1,大返回1,相等返回0
|
|
|
* @param a
|
|
|
* @param b
|
|
|
* @return
|
|
|
*/
|
|
|
int cmp(unsigned *a, unsigned *b) {
|
|
|
for (int i = 0; i < 4; ++i) {
|
|
|
if (a[i] < b[i]) return -1;
|
|
|
if (a[i] > b[i]) return 1;
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int main() {
|
|
|
//输入几个IP地址
|
|
|
while (scanf("%d", &m) != -1) {
|
|
|
//读入第一次的ip地址
|
|
|
scanf("%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
|
|
|
for (i = 0; i < 4; ++i) ipmax[i] = ipmin[i] = ip[i]; //初始化最大值与最小值
|
|
|
|
|
|
//先减减,再循环,因为第一个读取过了
|
|
|
while (--m) {
|
|
|
scanf("%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
|
|
|
//如果比最大的大,那么替换掉最大的IP
|
|
|
if (cmp(ip, ipmax) == 1)
|
|
|
for (i = 0; i < 4; ++i) ipmax[i] = ip[i];
|
|
|
else if (cmp(ip, ipmin) == -1) //如果比最小的小,那么替换掉最小的IP
|
|
|
for (i = 0; i < 4; ++i) ipmin[i] = ip[i];
|
|
|
}
|
|
|
for (i = 0; i < 4; ++i) {
|
|
|
// 原理: https://www.cnblogs.com/xienaoban/p/6798101.html
|
|
|
if (i == 0 || mask[i - 1] == 255) {
|
|
|
//最大最小两个ip进行异或运算,目的是找出第一个开始不一样的地方,然后再与1111 1111(二进制,即255)异或运算,
|
|
|
// 相当于取反,但是这里不能直接使用取反运算“~”
|
|
|
mask[i] = 255 ^ (ipmax[i] ^ ipmin[i]);
|
|
|
//因为一个unsigned有32位,会使得比1111 1111高位的0也取反。于是得到子网掩码的雏形。
|
|
|
// 而子网掩码前n位连续为1,后32-n位连续为0,这个雏形仅仅办到了前n位为1,所以得想办法把后32-n位清零
|
|
|
for (int j = 0; j <= 8; ++j)
|
|
|
if ((mask[i] >> j) == (255 >> j)) {
|
|
|
mask[i] = ((mask[i] >> j) << j);
|
|
|
break;
|
|
|
}
|
|
|
} else { mask[i] = 0; }
|
|
|
}
|
|
|
printf("%u.%u.%u.%u\n", mask[0] & ipmax[0], mask[1] & ipmax[1], mask[2] & ipmax[2], mask[3] & ipmax[3]);
|
|
|
printf("%u.%u.%u.%u\n", mask[0], mask[1], mask[2], mask[3]);
|
|
|
}
|
|
|
return 0;
|
|
|
} |