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