首页 > ACM题库 > HDU-杭电 > hdu 2207 IP的计算(二)[解题报告]C++
2014
01-04

hdu 2207 IP的计算(二)[解题报告]C++

IP的计算(二)

问题描述 :

不知道你是否注意过你的电脑上下面的网络信息:
“连接状态:
地址类型:          通过DHCP指派
  IP地址:          60.176.38.23
  子网掩码:          255.255.252.0
  默认网关:          60.176.36.1
  首选DNS服务器:      210.32.32.1
  备用DNS服务器:      210.32.32.10

我用最近学习的网络知识,来一一向你解释下(如果有误,恳请指正,谢谢):
1)  一个主机的适配器(网卡)或者一个路由器的适配器与网络的接口的IP地址(IP地址是指接口上的地址)可以由主机用户手工配置,也可以由专用的DHCP服务器来分配,DHCP即动态主机配置协议。
2)  IP地址,我想不需要解释了吧?不过需要说明下,IP地址分网络号部分和主机号部分,网络号在前,主机号在后,用可变长的子网划分的方法来标志一个IP地址的话,IP地址可以写成如60.176.36.0/x,其中x表示最开始的x位为网络号部分,后面的32-x位为主机号部分,也就是说,这个子网内部可以分配的IP地址最多有(2^(32-x))-2个(对于主机号全0和全1的IP,具有特殊意义,不能分配给主机)。注意,对于网络管理员来说,他要组建一个网络,必须要申请一定的IP地址空间,但是IP地址空间是有限的,因此不能任意分配(这些IP地址空间需要到特定的ISP去申请),因此必须因地制宜,分配满足需要但是最小的地址空间。
3)  子网掩码的作用就是为了让主机快速的读出一个IP地址中网络号部分,以备快速的定位子网,我们只需要用IP地址与子网掩码进行与操作,就能读出网络号部分,因此可见子网掩码中前x位全部是1,后面全部是0.
4)  默认网关是指一个AS(自治系统)对外部其他的AS进行分组交换的一个路由器,当然也有相应的IP地址。
5)  DNS是域名系统,其中最基本的作用就是域名与IP地址之间进行转换,acm.hdu.edu.cn是一个域名,而192.168.100.10是严格格式的IP,而域名可以有多个,如acm.split.hdu.edu.cn也可以指相同的网站,DNS服务器有庞大的分布式数据库,用来保存这些映射关系。
6)  对于一个组建的一个子网,一定会有一台服务器来提供服务,这台服务器必须由管理员设置一个固定IP地址
Hint

请注意,服务器的IP也是子网内的


现在你就是一个网络管理员,你需要组建一个局域网络,已知该网络中某时刻最大可能连接入网的主机个数(不同时刻,连接入网的主机数量在不断变化),问如果对于一台特定的主机,该如何设定其子网掩码,才能让主机获得该子网的正确的网络号部分。

输入:

输入有多个case,每个case有一个正整数字(0<N<10000000),表示该子网最大可能连接进来的主机的个数。

输出:

输入有多个case,每个case有一个正整数字(0<N<10000000),表示该子网最大可能连接进来的主机的个数。

样例输入:

10

样例输出:

255.255.255.240

这题是大水题。不过我用了一种比较诡异的写法,也不是为了装逼,主要是为了熟悉一下bitset的用法以及数据类型的转换。

/*
 * hdu2207/win.cpp
 * Created on: 2012-11-5
 * Author    : ben
 */
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <functional>
#include <numeric>
#include <cctype>
#include <bitset>
using namespace std;

int main() {
#ifndef ONLINE_JUDGE
    freopen("data.in", "r", stdin);
#endif
    int n;
    while(scanf("%d", &n) == 1) {
        n += 2;
        string temp("11111111111111111111111111111111");
        for(int i = 31; i > 0; i--) {
            if(n > 0) {
                temp[i] = '0';
            }
            n >>= 1;
        }
        bitset<32> b(temp);
        unsigned char *p = (unsigned char *)(&b);
        for(int i = 3; i > 0; i--) {
            printf("%u.", (unsigned int)p[i]);
        }
        printf("%u\n", (unsigned int)p[0]);
    }
    return 0;
}

解题转自:http://www.cnblogs.com/moonbay/archive/2012/11/05/2755049.html


  1. 思路二可以用一个长度为k的队列来实现,入队后判断下队尾元素的next指针是否为空,若为空,则出队指针即为所求。