You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

56 lines
2.3 KiB

2 years ago
#include <bits/stdc++.h>
using namespace std;
unsigned i, m, ip[4], ipmax[4], ipmin[4], mask[4];
/**
* -110
* @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;
}