Alexis administrator of IP networks. His clients have a bunch of individual IPaddresses and he decided to group all those IP addresses into the smallestpossible IP network.
Each IP addressis a 4-byte number that is written byte-by-byte in a decimal dot-separatednotation “byte0.byte1.byte2.byte3” (quotes are added for clarity). Each byte iswritten as a decimal number from 0 to 255 (inclusive) without extra leadingzeroes.
IP network isdescribed by two 4-byte numbers — network address and network mask. Bothnetwork address and network mask are written in the same notation as IPaddresses.
In order to understand the meaning ofnetwork address and network mask you have to consider their binaryrepresentation. Binary representation of IP address, network address, andnetwork mask consists of 32 bits: 8 bits for byte0 (most significant to leastsignificant), followed by 8 bits for byte1, followed by 8 bits for byte2, andfollowed by 8 bits for byte3.
IP network contains a range of 2nIP addresses where 0 ≤ n ≤ 32.Network mask always has 32−n firstbits set to one, and n last bits setto zero in its binary representation. Network address has arbitrary 32 −n first bits, and n last bits set to zero in its binary representation. IP networkcontains all IP addresses whose 32 −n firstbits are equal to 32 −n first bits ofnetwork address with arbitrary n lastbits. We say that one IP network is smaller than the other IP network if it containsfewer IP addresses.
For example, IP network with networkaddress 194.85.160.176 and network mask 255.255.255.248 contains 8 IP addressesfrom 194.85.160.176 to 194.85.160.183 (inclusive).
Input
Theinput file will contain several test cases, each of them as described below.
The first line of theinput file contains a single integer number m(1 ≤m≤ 1000). The following m lines contain IP addresses, oneaddress on a line. Each IP address may appear more than once in the input file.
Output
For each test case, writeto the output file two lines that describe the smallest possible IP networkthat contains all IP addresses from the input file. Write network address onthe first line and network mask on the second line.
Sample Input
3
194.85.160.177
194.85.160.183
194.85.160.178
Sample Output
194.85.160.176
255.255.255.248
【思路】
给出一堆IP地址,求包含IP地址最少的网络,同时求子网掩码。需要掌握一定的网络知识才能做这道题,在满足包含题述IP地址的前提下当,最大的那个子网掩码和任意IP地址(需包含在该网中)做与运算就可以得到答案了。可以将最大和最小的IP分别求出,再从大到小试一下子网掩码,能够使所有IP地址都归属于同一个网络的就是所求子网掩码,再做与运算便是最小网络地址。
【代码】
#include <iostream>
#include <cstring>
#include <sstream>
using namespace std;
const int MAXN = 1005, INF = 0x3f3f3f3f;
const int NUM[9] = {255, 254, 252, 248, 240, 224, 192, 128, 0};
struct ip {
int a1, a2, a3, a4;
bool operator<(const ip &another) const
{
if (a1 == another.a1)
if (a2 == another.a2)
if (a3 == another.a3)
return a4 < another.a4;
else
return a3 < another.a3;
else
return a2 < another.a2;
else
return a1 < another.a1;
}
ip operator&(const ip &another) const
{
ip ans;
ans.a1 = a1 & another.a1;
ans.a2 = a2 & another.a2;
ans.a3 = a3 & another.a3;
ans.a4 = a4 & another.a4;
return ans;
}
bool operator==(const ip &another) const
{
return (a1 == another.a1 && a2 == another.a2 && a3 == another.a3 && a4 == another.a4);
}
const ip &operator=(const ip &another)
{
a1 = another.a1;
a2 = another.a2;
a3 = another.a3;
a4 = another.a4;
return *this;
}
};
int n;
ip a[MAXN];
int main()
{
while (cin >> n) {
cin.get();
string buff;
stringstream stream;
ip minone, maxone;
minone.a1 = minone.a2 = minone.a3 = minone.a4 = INF;
maxone.a1 = maxone.a2 = maxone.a3 = maxone.a4 = 0;
for (int i = 1; i <= n; i++) {
getline(cin, buff);
int len = buff.length();
for (int j = 0; j < len; j++)
if (buff[j] == '.') buff[j] = ' ';
stream.str(""); stream.clear();
stream << buff;
stream >> a[i].a1 >> a[i].a2 >> a[i].a3 >> a[i].a4;
if (a[i] < minone) minone = a[i];
if (maxone < a[i]) maxone = a[i];
}
ip mask;
mask.a1 = mask.a2 = mask.a3 = mask.a4 = NUM[0];
bool flag = false;
for (int i = 0; i <= 8 && !flag; i++) {
mask.a4 = NUM[i];
if ((maxone & mask) == (minone & mask)) flag = true;
}
for (int i = 0; i <= 8 && !flag; i++) {
mask.a3 = NUM[i];
if ((maxone & mask) == (minone & mask)) flag = true;
}
for (int i = 0; i <= 8 && !flag; i++) {
mask.a2 = NUM[i];
if ((maxone & mask) == (minone & mask)) flag = true;
}
for (int i = 0; i <= 8 && !flag; i++) {
mask.a1 = NUM[i];
if ((maxone & mask) == (minone & mask)) flag = true;
}
ip ans = (minone & mask);
cout << ans.a1 << "." << ans.a2 << "." << ans.a3 << "." << ans.a4 << endl;
cout << mask.a1 << "." << mask.a2 << "." << mask.a3 << "." << mask.a4 << endl;
}
return 0;
}