习题4-5 IP网络(IP Networks, ACM/ICPC NEERC 2005, UVa1590)

可以用一个网络地址和一个子网掩码描述一个子网(即连续的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

地址最少的网络),包含所有这些输入地址。

例如,若输入3个IP地址:194.85.160.177、194.85.160.183和194.85.160.178,包含上述3

个地址的最小网络的网络地址为194.85.160.176,子网掩码为255.255.255.248。

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

【注意:他可能有很多组输入,而每组输出之间没有空行】

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=833&problem=4465&mosmsg=Submission+received+with+ID+21184770

思路:

1、先将所有ip存起来,用数组或容器什么的。

2、转换二进制

3、从第一位开始,诸位比较所有的ip在这一位上的数字一样否

4、判断出最小网络位数,即掩码为1的位数。

5、转换十进制

(我用来存二进制的ip用的是string)

(用了下vector,当然也可以用数组存,一个32*1000的数组)


/*
110000100101010110100000_10110001
110000100101010110100000_10110111
110000100101010110100000_10110010 11000010010101011010000010110000
11111111111111111111111111111000
*/
//特殊情况:只输入一个IP地址,这时掩码应该32位1
#include<iostream>
#include<stack>
#include<string>
#include<vector>
#include<cmath>
#include<cstdio>
using namespace std;
string binary(int dec)
{
string str="00000000";
stack<int> s;
int bin=0;
for(int i=7;i>=0;i--)
{
//s.push(dec%2);
str[i]=dec%2+'0';
dec /= 2;
}
// while(!s.empty())
// {
// bin = bin*10 + s.top();
// s.pop();
// }
// return bin;
return str;
}
int decimal(string bin)
{
int dec =0;
for(int i=0;i<8;i++) //从高位开始
{
dec += (int)pow(2,8-i-1)* (bin[i]-'0');
}
return dec;
}
int main()
{
int T;
while(cin>>T)
{
vector<string>ip; // 存储输入的所有ip
int num=0;
if(T==1) //防止只输入一个地址的特殊情况
num=32;
while(T--) //输入
{
int a[4];
string str;
scanf("%d.%d.%d.%d",&a[0],&a[1],&a[2],&a[3]);
for(int i=0;i<4;i++)
{
str += binary(a[i]);
}
ip.push_back(str);
}
for(int j=0;j<32;j++) //判断相等的位数
{
int iff=0;
for(int i=1;i<ip.size();i++)
{
//cout<<ip.at(i)<<endl;
if(ip.at(0)[j] == ip.at(i)[j]) //这一位相等
{
iff=1;
}
else
{
iff=0;
break;
}
}
if(iff) //这一位相等,掩码位数加一
num++;
else
break;
}
string zero="00000000"; //备用0
string mask,minip;
int score[4];//存储最小网络的四个十进制ip地址段
int score2[4];//存储mask的四个十进制的ip地址段 for(int i=1;i<=32-num;i++) //先从最后开始补0
{
minip='0'+minip;
mask='0'+mask;
}
for(int i=num-1;i>=0;i--) //倒的补
{
minip=ip[0].at(i)+minip;
mask='1'+mask;
} // cout<<num<<endl;
// for(int i=0;i<ip.size();i++)
// cout<<ip[i]<<endl;
// cout<<endl;
// cout<<mask<<endl; for(int i=0;i<4;i++) //运算最小网络
{
score[i] =decimal(minip.substr(i*8,8));
score2[i] =decimal(mask.substr(i*8,8));
//以下淘汰的方法是:边变换,边比对是否位数到了最小网络位。
//比较上面的先做好一个最小网络的二进制地址,然后在直接变换。要更复杂
// if(i*8+8>num)
// {
// //cout<<i*8<<" "<<num<<endl;
// //cout<<ip[0].substr(i*8,num-i*8)<<"|"<<zero.substr(0,32-num)<<endl;
// score[i]=decimal(ip[0].substr(i*8,num-i*8)+zero.substr(0,32-num));
// }
// else
// {
// //cout<<ip[0].substr(i*8,8)<<endl;
// score[i]=decimal(ip[0].substr(i*8,8));
// }
} printf("%d.%d.%d.%d\n",score[0],score[1],score[2],score[3]);
printf("%d.%d.%d.%d\n",score2[0],score2[1],score2[2],score2[3]);
}
return 0;
}
//AC at 2018/4/22

(题外话:好在上学期的网络课设就是算ip地址,所以这道题我才想了半个多小时就有思路了(哭))

uva 1590 - IP Networks(IP地址)的更多相关文章

  1. IP Networks UVA - 1590

     Alex is administrator of IP networks. His clients have a bunch of individual IP addresses and he de ...

  2. UVa 1590 IP网络(简单位运算)

    Description   Alex is administrator of IP networks. His clients have a bunch of individual IP addres ...

  3. [刷题]算法竞赛入门经典(第2版) 4-5/UVa1590 - IP Networks

    书上具体所有题目:http://pan.baidu.com/s/1hssH0KO 代码:(Accepted,0 ms) //UVa1590 - IP Networks #include<iost ...

  4. Java获取本机的IP与MAC地址

    有些机器有许多虚拟的网卡,获取IP地址时会出现一些意外,所以需要一些验证: // 获取mac地址 public static String getMacAddress() { try { Enumer ...

  5. CIDR详解和ip最长地址前缀匹配

    1.CIDR是什么 无类域间路由(CIDR)编址方案 摒弃传统的基于类的地址分配方式,允许使用任意长度的地址前缀,有效提高地址空间的利用率. 就是一个ip加一个网络掩码,不过这个掩码不是之前只有3个值 ...

  6. 几种获取IP 根据IP获取地址的方法 JS,第三方 新浪 网易 腾讯

    第一种是利用纯真ip数据库,这个可以在网上找到很多,缺点是更新有点慢. 第二种是利用门户网站的接口 目前已知的有腾讯.新浪.网易.搜狐和Google提供IP地址查询API,但是找得到的只有腾讯.新浪和 ...

  7. C#实现根据IP 查找真实地址

    IPScanner.cs public class IPScanner { private byte[] data; Regex regex = new Regex(@"(((\d{1,2} ...

  8. 获得Unix/Linux系统中的IP、MAC地址等信息

    获得Unix/Linux系统中的IP.MAC地址等信息 中高级  |  2010-07-13 16:03  |  分类:①C语言. Unix/Linux. 网络编程 ②手册  |  4,471 次阅读 ...

  9. 纯真IP根据IP地址获得地址

    <?php /** * 纯真IP根据IP地址获得地址 */ class ipLocation { public $fp; public $firstip; //第一条ip索引的偏移地址 publ ...

随机推荐

  1. 【转】ubuntu右键在当前位置打开终端

    ubuntu右键在当前位置打开终端   ubuntu增加右键命令:   在终端中打开   软件中心:   搜索nautilus-open-terminal安装   命令行:   sudo apt-ge ...

  2. zabbix系列之二——安装

    1Getting zabbix Four ways of getting: Index Option note 1 Install it from the distribution packages ...

  3. pjax 和 ajax 的区别

    pjax 是一个 jQuery 插件,它通过 ajax 和 pushState 技术提供了极速的(无刷新 ajax 加载)浏览体验,并且保持了真实的地址.网页标题,浏览器的后退(前进)按钮也可以正常使 ...

  4. [UI] MFD UI kit

    MFD UI kit https://dribbble.com/whaledesigned

  5. 产生渐变色的view

    产生渐变色的view 效果 源码 https://github.com/YouXianMing/UI-Component-Collection // // GradientColorView.h // ...

  6. 数据库启动丢失MSVCP120.dll

    在自己第一次安装数据库的时候发生了很多问题,,首当其冲的就是数据库启动时丢失MSVCP120.dll,这里就不配图了(安装好了才想起来写一篇博客). 为什么安装不了? 这是因为系统缺失必要的运行库导致 ...

  7. in有两种用法:

    # in有两种用法: 1. 在for中. 是把每一个元素获取到赋值给前⾯的变量. 2. 不在for中. 判断xxx是否出现在str中. #len() 为内置函数,输出为1,2,3,4....., 长度 ...

  8. 面向对象程序设计_tesk1_寒假伊始

    大一下学期的自我目标(要求包含对大一上学期的总结.对面向对象课程完成后学习到的能力的预期,对面向对象课程的期望.对编程和专业能力的愿景规划) 在大学的第一个学期,相信很多人都是在得过且过度过,我也不例 ...

  9. python3 装饰器全解

    本章结构: 1.理解装饰器的前提准备 2.装饰器:无参/带参的被装饰函数,无参/带参的装饰函数 3.装饰器的缺点 4.python3的内置装饰器 5.本文参考 理解装饰器的前提:1.所有东西都是对象( ...

  10. 解决win7远程桌面连接时发生身份验证错误的方法

    远程桌面连接,是我们比较常用的一个功能了,但有时突然不能用了,以下是我遇到该问题,并解决该问题的方法.连接时报的是“发生身份验证错误,要求的函数不受支持”,解决之后细想一下,该问题好像是在我在电脑上安 ...