1. 程式人生 > >UVALive3520 UVa1590 POJ2799 IP Networks【進位制+位運算】

UVALive3520 UVa1590 POJ2799 IP Networks【進位制+位運算】

Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 2392Accepted: 919

Description

Alex is administrator of IP networks. His clients have a bunch of individual IP addresses and he decidedto 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 from0 to 255 (inclusive) without extra leading zeroes.

IP network is described by two 4-byte numbers - network address and network mask. Both networkaddress 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 has 32-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 lastbits. 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 first line of the input 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 a case.

Output

Write to the output two lines that describe the smallest possible IP network that contains all IP addresses from this case. Write network address on the first line and network mask on the secondline.

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

Source


問題簡述

  一個網路地址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\n", 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\n", 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;
}