可以用一个网络地址和一个子网掩码描述一个子网(即连续的IP地址范围)。其中子网掩码包含32个二进制位,前32-n位为1,后n位为0,网络地址的前32-n位任意,后n位为0。所有前32-n位和网络地址相同的IP都属于此网络。
例如,网络地址为194.85.160.176(二进制为11000010|01010101|10100000|10110000),子网掩码为255.255.255.248(二进制为11111111|11111111|11111111|11111000),则该子网的IP地址范围是194.85.160.176~194.85.160.183。输入一些IP地址,求最小的网络(即包含IP地址最少的网络),包含所有这些输入地址。
提示:ip的四个部分分别处理,每一部分找出最大值的最小值,然后判断是其二进制最后几位不同,得出子网掩码;用任意一个IP与子网掩码进行按位与运算得出最小IP;
样例输入:
3
194.85.160.177
194.85.160.183
194.85.160.178
样例输出:
194.85.160.176
255.255.255.248
样例输入:
2
202 101 244 102
202 101 244 108
样例输出:
202.101.244.96
255.255.255.240
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
int zwym_table[9] = { 255, 254, 252, 248, 240, 224, 192, 128, 0 };
int main()
{
int ip[4][1024];
int m;
cin >> m;
memset(ip, 0, sizeof(ip));
int zwym[4];
int minip[4];
for (int i = 0; i<m; i++)
cin>>ip[0][i]>>ip[1][i]>>ip[2][i]>>ip[3][i];
for (int i = 0; i<4; i++)
{
int dif = 0, x, j;
int p, q;
sort(ip[i], ip[i] + m);
p = ip[i][m - 1];
q = ip[i][0];
for (j = 1; j <= 8; j++)
{
if (p % 2 != q % 2)
dif = j;
p = p / 2;
q = q / 2;
}
zwym[i] = zwym_table[dif];
minip[i] = ip[i][0] & zwym[i];
}
for (int i = 0; i<4; i++)
{
if (zwym[i] != 255)
{
for (i = i + 1; i<4; i++)
{
zwym[i] = 0;
minip[i] = 0;
}
break;
}
}
printf("%d.%d.%d.%d\n", minip[0], minip[1], minip[2], minip[3]);
printf("%d.%d.%d.%d\n", zwym[0], zwym[1], zwym[2], zwym[3]);
return 0;
}