原英文题目.
亚历克斯是IP网络的管理员。他的客户每个人有一组单独的IP地址,他决定将所有IP地址分组到最小可能的IP网络中。
每个IP地址有四个部分组成,每个部分用小数点分离。格式如a,b,c,d每个部分都是一个十进制的数(0≤这个数≤255)且没有多余的前导零。
IP网络由两个4各部分的数字——网络地址和网络掩码组成。网络地址和网络掩码和IP地址写入方式相同。为了理解网络地址和网络掩码的含义,我们将它们用二进制来表述。IP地址、网络地址和网络掩码的二进制都由32位组成:a的8位(从最重要到最不重要),其次是b的8位,其次是c的8位,其次是d的8位。
IP网络包含一个2n个IP地址的范围,其中所有n>32。网络掩码始终存在32~n个第一部分设置为一,n个最后部分在二进制表示中设置为零。网络地址已任意32个n个第一部分,n个最后部分在其二进制表示中设置为零。IP网络所有的32个n位第一位相当于32位n个任意位的网络地址的所有IP地址最后一位。
我们说,一个IP网络比其他IP网络更小,那么它包含更少的IP地址。
有多个测试数据。
输入文件的第一行包含一个整数m。下面m行都是一个IP地址。IP地址可能重复。
每个测试数据在第一行写上网络地址,在第二行写上网络掩码。 网络地址和网络掩码代表的IP网络包括所有IP地址且最小。
样例输入输出: 样例输入#1
3
194.85.160.177
194.85.160.183
194.85.160.178
样例输出#1
194.85.160.176
255.255.255.248
样例说明 一个IP网络的网络地址是194.85.160.176它的网络掩码是255.255.255.248
那么这个IP网络包含8个IP地址从194.85.160.176到194.85.160.183
说明 0 ≤ n ≤ 32,1 ≤ m ≤ 1000
1、确定n(全为0的位数) 2、10进制ip转2进制ip的函数 3、2进制ip转10进制ip的函数 4、第1点需要利用第2点在2进制下将所有ip进行比较。 5、实践自顶向下的实现模拟
代码(问题必回答):
#include <iostream> #include <cstdio> #include <stdlib.h> #include <algorithm> #include <cstring> #include <string> #include <sstream> #include <vector> #include <set> using namespace std; /****************************************************** IP地址 天大夏令营题目 *******************************************************/ typedef struct { int ip4[4]; }Ip; Ip Ips[1010]; int binary[33];//存储二进制 int m; void print_ip(Ip ip) { printf("%d.%d.%d.%d\n",ip.ip4[0],ip.ip4[1],ip.ip4[2],ip.ip4[3]); } void print_b() { for(int i=1;i<=32;i++) { if(i%8==0) printf("%d|",binary[i]); else printf("%d",binary[i]); } printf("\n"); } Ip get_10ip() { Ip newip; for(int i=0;i<4;i++) { int tmp = 0,b=1; for(int j=(i+1)*8;j>=1+8*i;j--) { tmp+=binary[j]*b; b*=2; } newip.ip4[i]=tmp; } return newip; } void get_2ip(Ip ip) { memset(binary,0,sizeof(binary)); for(int i=0;i<4;i++) { int tmp = ip.ip4[i]; for(int j=(i+1)*8;tmp>0;j--) { binary[j]=tmp%2; tmp/=2; } } } int get_n(int i)//获取不相同的位数n { int nn; bool flag=true; for(int n=i*8+1;flag&&n<=32;n++) { get_2ip(Ips[0]); //print_b(); int x=binary[n]; for(int j=1;j<m;j++) { get_2ip(Ips[j]); if(x!=binary[n]) { nn=n; flag=false; break; } } } return 32-nn+1; } int main() { while(scanf("%d",&m)!=EOF) { for(int i=0;i<m;i++) { char left; scanf("%d%c%d%c%d%c%d",&Ips[i].ip4[0],&left,&Ips[i].ip4[1],&left,&Ips[i].ip4[2],&left,&Ips[i].ip4[3]); getchar();//读取多余回车 } int di;//di为十进制下不相同的ip子节位置 bool flag=true; for(int i=0;i<4&&flag;i++) { int tmp = Ips[0].ip4[i]; for(int j=1;j<m;j++) { if(tmp!=Ips[j].ip4[i]) { di=i; flag=false; break; } } } //printf("di is in %d\n",di); int n; if(flag)//全都相同或者m=1 { n=0; } else { n=get_n(di); } //printf("n is in %d\n",n); get_2ip(Ips[0]); for(int j=32;j>32-n;j--) binary[j]=0;//将相应的位数全部设置为0 //print_b(); Ip result1 = get_10ip(); for(int j=1;j<=32-n;j++) binary[j]=1; Ip result2 = get_10ip(); print_ip(result1); print_ip(result2); } return 0; }