zoukankan      html  css  js  c++  java
  • UVALive3520 UVa1590 POJ2799 IP Networks【进制+位运算】

    Regionals 2005 >> Europe - Northeastern


    问题链接UVALive3520 UVa1590 POJ2799 IP Networks

    问题简述

    一个网络地址ip和一个子网掩码可以描述一个子网。子网是一个数,它是包含4组8位二进制数,总共32位二进制数,前n个位为1,后32-n个位为0,如:255.255.255.48(11111111|11111111|11111111|11111000) 表示某个ip地址如果和A的前n位相等则说明其属于这个子网。
    现给定m个网络地址组成一子网,求该子网的最小范围的首地址和子网掩码。

    问题分析

    需要计算ip地址从哪一位开始不同,以此计算子网掩码

    再利用子网掩码计算最小ip。

    程序说明:这里给出两个程序,后一种解法没有使用数组,自然要优于前一种解法。两个程序的计算方式不同,结果是一样的。

    参考链接:(略)

    题记:存储要能省则省。


    AC的C++程序如下:

    /* UVALive3520 UVa1590 POJ2799 IP Networks */
    
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    
    const int MOD = (1 << 8);
    const int N = 1000;
    unsigned int ip[N];
    
    void output_result(unsigned int x)
    {
        int byte0, byte1, byte2, byte3;
    
    
        byte3 = x % MOD;
        x >>= 8;
        byte2 = x % MOD;
        x >>= 8;
        byte1 = x % MOD;
        x >>= 8;
        byte0 = x;
    
        printf("%d.%d.%d.%d
    ", byte0, byte1, byte2, byte3);
    }
    
    int main()
    {
        int m;
        unsigned byte0, byte1, byte2, byte3;
    
        while(cin >> m)
        {
            memset(ip, 0, sizeof(ip));
    
            for(int i=0; i<m; i++) {
                scanf("%d.%d.%d.%d", &byte0, &byte1, &byte2, &byte3);
    
                ip[i] = (byte0 << 24) + (byte1 << 16) + (byte2 << 8) + byte3;
            }
    
            unsigned int mask = ~0;
            for(int i=1; i<m; i++)
            {
                unsigned int q = ip[i] ^ ip[0];
                while(q) {
                    mask &= ~(q | (q-1));
                    q = q & (q-1);
                }
            }
    
            output_result(ip[0] & mask);
            output_result(mask);
        }
    
        return 0;
    }


    AC的C++程序如下:

    /* UVALive3520 UVa1590 POJ2799 IP Networks */
    
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    
    const int MOD = (1 << 8);
    const int N = 32;
    
    int visited[N];
    
    void output_result(unsigned int x)
    {
        int  byte0, byte1, byte2, byte3;
    
    
        byte3 = x % MOD;
        x >>= 8;
        byte2 = x % MOD;
        x >>= 8;
        byte1 = x % MOD;
        x >>= 8;
        byte0 = x;
    
        printf("%d.%d.%d.%d
    ", byte0, byte1, byte2, byte3);
    }
    
    int main()
    {
        int m;
        unsigned int  byte0, byte1, byte2, byte3, ip, mask, ip2;
        int bit;
    
        while(cin >> m) {
            memset(visited, -1, sizeof(visited));
    
            while(m--) {
                scanf("%d.%d.%d.%d", &byte0, &byte1, &byte2, &byte3);
    
                ip = (byte0 << 24) + (byte1 << 16) + (byte2 << 8) + byte3;
    
                ip2 = ip;
                for(int i=0; i<N; i++) {
                    bit = ip2 & 1LL;
    
                    if(visited[i] == -1)
                        visited[i] = bit;
                    else if(visited[i] != bit)
                        visited[i] = 2;
    
                    ip2 >>= 1;
                }
            }
    
            int pos;
            for(pos=N-1; pos>=0; pos--)
                if(visited[pos] == 2)
                    break;
    
            mask = 0;
            bit = 1;
            for(int j=0; j<N; j++) {
                if(j > pos)
                    mask += bit;
                bit <<= 1;
            }
    
            output_result(ip & mask);
            output_result(mask);
        }
    
        return 0;
    }



  • 相关阅读:
    python定义函数时的默认返回值
    【UNIX网络编程】配置unp.h和apueerror.h
    【UNIX网络编程】套接字编程简介
    【UNIX网络编程】概述
    【VSCode】Ubuntu下VSC编译运行c++程序
    【UNIX网络编程】传输层:TCP、UDP和SCTP
    nginx跨域配置
    centOS7.*安装nginx和简单使用
    nginx日志切割
    nginx静态资源防盗链
  • 原文地址:https://www.cnblogs.com/tigerisland/p/7563770.html
Copyright © 2011-2022 走看看