BFS:UVa1590-IP Networks (子网掩码相关知识)
IP Networks
Alex is administrator of IP networks. His clients have a bunch of individual IP addresses and he decided to group all those IP addresses into the smallest possible IP network. Each IP address is a 4-byte number that is written byte-by-byte in a decimal dot-separated notation “byte0.byte1.byte2.byte3” (quotes are added for clarity). Each byte is written as a decimal number from 0 to 255 (inclusive) without extra leading zeroes. IP network is described by two 4-byte numbers — network address and network mask. Both network address and network mask are written in the same notation as IP addresses. In order to understand the meaning of network address and network mask you have to consider their binary representation. Binary representation of IP address, network address, and network mask consists of 32 bits: 8 bits for byte0 (most significant to least significant), followed by 8 bits for byte1, followed by 8 bits for byte2, and followed by 8 bits for byte3. IP network contains a range of 2n IP addresses where 0 ≤ n ≤ 32. Network mask always has32 −n first bits set to one, and n last bits set to 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 network contains all IP addresses whose 32−n first bits are equal to 32−n first bits of network address with arbitrary n last bits. We say that one IP network is smaller than the other IP network if it contains fewer IP addresses. For example, IP network with network address 194.85.160.176 and network mask 255.255.255.248 contains 8 IP addresses from 194.85.160.176 to 194.85.160.183 (inclusive).
Input
The input file will contain several test cases, each of them as described below. The first line of the input file contains a single integer number m (1 ≤ m ≤ 1000). The following m lines contain IP addresses, one address on a line. Each IP address may appear more than once in the input file.
Output
For each test case, write to the output file two lines that describe the smallest possible IP network that contains all IP addresses from the input file. Write network address on the 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地址一样,长度也是32位,点分十进制表示,每部分0~255,但是跟IP地址不同的是,子网掩码只能由连续的1和0组成,也就是说,把这32位从任意位置分开,左边只能全是1,右边只能全是0。比如11111111.11111111.11111111.11111000(255.255.255.248)就是合法的子网掩码,而11000000.10101000.00000001.00000000(192.168.1.0)就不合法(可以尝试一下在计算机上给网络连接手动分配子网掩码,看看它会怎么提示你)。给定两个IP,假设其子网掩码二进制有x个连续的1,则如果这两个IP的二进制前x位对应相等,那么这两个IP就属于同一网段,也就是属于同一个子网。
如果给定一个子网掩码和一个IP,就可以求出这个IP所在子网的最小IP,方法是将IP的二进制与子网掩码的二进制进行按位与运算,原理是,子网掩码为1的二进制位,要求子网内所有IP的这一位必须全部相等,而子网掩码为0的位不作要求,也就是说,给定一个IP,子网内最小IP对应的子网掩码为1的位必须跟给定IP一样,按位与的时候,给定IP与子网掩码是1的位按位与后的结果不变,子网掩码0的位按位与后为0(恰好是最小),这样按位与运算结束后,得到的IP就是子网内最小IP(说的我自己都有点晕乎了,想弄明白这个,必须了解位运算和子网掩码的相关知识)。
说了这么多,都只是预备知识,下面可以切入正题,给定一些IP地址,求出子网掩码和子网内最小IP。
根据上面所说,这个题只要求出子网掩码,然后与给定的任意IP进行按位与运算,就可以得到最小IP了。那么现在关键就是求子网掩码了,既然给定的这一些IP都是一个网段的,那么找到这些IP里的最小IP和最大IP,然后找到这两个IP的二进制从左往右看哪一位最先出现不同(异或运算可解),就可以知道子网掩码里有几个连续的1,自然就得到子网掩码了,然后最小IP便迎刃而解。所以这个题其实很简单,只要了解点IP地址相关知识即可。
然后自己写了一个贼他妈弱智的代码,感觉自己没有学过算法,居然过了。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 40;
int num[1010][maxn];
int ans[maxn];
void change_bin_num(int num2,int t,int i)
{
while(num2)
{
if(num2%2)
num[i][t] = 1;
num2 /= 2;
t--;
}
}
void change_bin(int a,int b,int c,int d,int i)//将输入的全改成二进制
{
change_bin_num(d,32,i);
change_bin_num(c,24,i);
change_bin_num(b,16,i);
change_bin_num(a,8,i);
}
void print_ans(int part)
{
int res = 1;
int ans2 = 0;
for(int i=part; i>part-8; i--)
{
ans2 += ans[i]*res;
res *= 2;
}
printf("%d",ans2);
}
int get_ans1(int m)
{
int num2 = 0;
bool flag = false;
for(int i=1; i<=32; i++)
{
for(int j=1; j<=m; j++)
{
int now = num[1][i];
if(now != num[j][i])
{
flag = true;
break;
}
}
if(flag)
break;
num2++;
}
return num2;
}
void print_ans2(int now,int num2)
{
int ans2 = 0;
int res = 1;
for(int i=now+num2; i>now; i--)
{
ans2 += num[1][i]*res;
res *= 2;
}
printf("%d",ans2);
if(now + num2 <= 24)
printf(".");
}
void get_ans2(int num2)//打印最小的那个ip地址
{
int k = num2;
int part = 0,now = 0;
while(num2)
{
part++;
if((num2-8) >= 0)
print_ans2(now,8);
else
{
for(int i=k+1; i<=32; i++)//子网掩码0的部分对应的全为0
num[1][i] = 0;
print_ans2(now,8);
break;
}
num2 -= 8;
now += 8;
}
if(part >= 4)//记录打印了几部分,少的部分用0来填充
return ;
else
for(int i=part; i<4; i++)
{
printf("0");
if(i != 3)
printf(".");
}
}
int main()
{
int m;
while(~scanf("%d",&m))
{
memset(num,0,sizeof(num));
memset(ans,0,sizeof(ans));
for(int i=1; i<=m; i++)
{
int a,b,c,d;
scanf("%d.%d.%d.%d",&a,&b,&c,&d);//输入一点小技巧
change_bin(a,b,c,d,i);
}
int _num = get_ans1(m);//得到子网掩码最左边1的个数
get_ans2(_num);
printf("\n");
//打印子网掩码
for(int i=1; i<=_num; i++)
ans[i] = 1;
print_ans(8);
printf(".");
print_ans(16);
````
rintf(".");
print_ans(24);
printf(".");
print_ans(32);
printf("\n");
}
return 0;
}
大神的简洁代码
#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};//二进制中前8位全是1的值,前7位,前6位......
int main()
{
int ip[4][1024];
int m;
while(scanf("%d",&m)!=EOF)
{
memset(ip, 0, sizeof(ip));
int zwym[4];
int minip[4];
for(int i=0; i<m; i++)
scanf("%d.%d.%d.%d",&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;
}
BFS:UVa1590-IP Networks (子网掩码相关知识)的更多相关文章
- [刷题]算法竞赛入门经典(第2版) 4-5/UVa1590 - IP Networks
书上具体所有题目:http://pan.baidu.com/s/1hssH0KO 代码:(Accepted,0 ms) //UVa1590 - IP Networks #include<iost ...
- IP地址 子网掩码 默认网关 DNS(转)
突然被问到IP地址方面的知识,吓得我赶紧上网找一找资料,觉得这篇还是写得简单易懂,share一下. Key: 1.IP地址=网络地址+主机地址,(又称:主机号和网络号组成): 2.将IP地址和子网掩码 ...
- 读书笔记——网络编程与开发技术(3)基于TCP/IP协议的网络编程相关知识
TCP/IP协议:数据链路层,网络层,传输层,应用层. IP地址分为5类:A类.B类.C类.D类.E类. (A类.B类.C类是基本类,D类多用于多播传送,E类为保留类.) "*"表 ...
- 一文搞懂网络知识,IP、子网掩码、网关、DNS、端口号
网络的基本概念 客户端:应用 C/S(客户端/服务器) B/S(浏览器/服务器) 服务器:为客户端提供服务.数据.资源的机器 请求:客户端向服务器索取数据 响应:服务器对客户端请求作出反应,一般是返回 ...
- OSPF相关知识与实例配置【第一部分】
OSPF相关知识与实例配置[基本知识及多区域配置] OSPF(开放式最短路径优先协议)是一个基于链路状态的IGP,相比于RIP有无环路:收敛快:扩展性好等优点,也是现在用的最多的:所以这次实验就针对于 ...
- TCP/IP网络协议基础知识集锦[转]
引言 本篇属于TCP/IP协议的基础知识,重点介绍了TCP/IP协议簇的内容.作用以及TCP.UDP.IP三种常见网络协议相关的基础知识. 内容 TCP/IP协议簇是由OSI七层模型发展而来的,之所以 ...
- uva 1590 - IP Networks(IP地址)
习题4-5 IP网络(IP Networks, ACM/ICPC NEERC 2005, UVa1590) 可以用一个网络地址和一个子网掩码描述一个子网(即连续的IP地址范围).其中子网 掩码包含32 ...
- 【转载】前端面试“http全过程”将所有HTTP相关知识抛出来了...
原文:前端面试“http全过程”将所有HTTP相关知识抛出来了... 来一篇串通,一个http全过程的问题,把所有HTTP相关知识点都带过一遍 http全过程 输入域名(url)-->DNS映射 ...
- Zookeeper相关知识
一.Zookeeper是什么? Zookeeper 分布式服务框架是 Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务.状态同步服务. ...
随机推荐
- replcation set (复制集)配置过程 --mongodb
一,配置规划 复制集原理(基本构成是1主2从的结构,自带互相监控投票机制(Raft(MongoDB) Paxos(mysql MGR 用的是变种))如果发生主库宕机,复制集内部会进行投票选举,选择一 ...
- SPI接口的ETH芯片(ENC28J60/W5500)
一 ENC28J60:SPI接口.中断.复位.LED指示.可参看野火相应教程.简单的在单片机中实现网页服务器是参考AVRNET项目,复杂的是用LWIP协议栈.telnet用于用PC的TELNET可以远 ...
- Java VisualVM添加Visual GC插件
1.访问地址:https://visualvm.github.io/pluginscenters.html,找到自己JDK版本对应的插件下载地址(我的JDK版本为1.7.0_67): 2.点击该链接进 ...
- Angular2中实现基于TypeScript的对象合并方法:extend()
TypeScript里面没有现成的合并对象的方法,这里借鉴jQuery里的$.extend()方法.写了一个TypeScript的对象合并方法,使用方法和jQuery一样. 部分代码和jQuery代码 ...
- Redis list(列表)
Redis列表是简单的字符串列表,列表是有序的,列表中的元素可以重复. 可以添加一个元素到列表的头部(左边)或者尾部(右边) 一个列表最多可以包含 232 - 1 个元素 (40多亿). 1.lpus ...
- 洛谷 P1807 最长路_NOI导刊2010提高(07)
最长路 #include <iostream> #include <cstdio> #include <cstring> #include <queue> ...
- Nginx开启Gzip压缩提高页面加载速度
本文转自http://www.veryhuo.com/a/view/51706.html,如有侵权,请及时联系转载人删除! 在实际运维中,为了提高web页面的访问加载速度,一般会把静态资源(比如js. ...
- pre-empting taskintel手册-Chapter7-Task Management
这节描述了IA-32架构的任务管理功能,只有当处理器运行在保护模式的时候,这个功能才是有效的,这节的侧重点在32位任务和32位TSS结构上,关于16位的任务和16位TSS结构,请看7.6节,关于64位 ...
- oracle 数据导到 sql server
方法一: navicate:用法比较简单,选择工具-数据传输就可以了.目前测试了下暂时没遇到什么问题. 方法二: Microsoft SQL Server Migration Assistant 8. ...
- JDK的安装以及环境变量的配置
一.JDK的安装 1.百度搜索jdk1.8 2.进入网页选择Downloads 3. 选择电脑的版本(x86 32位 x64 64位) 4.下载好后,直接双击即可,一直下一步即可完成安装 二.环境变量 ...