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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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;
}