一:题目
给出m(1到10000之间)个IP地址,求他们最小的网络号和子网掩码

(一)样例输入

3          表示要获取的IP地址个数
194.85.160.177  IP地址
194.85.160.183
194.85.160.178

(二)样例输出

194.85.160.176
255.255.255.248
二:代码实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define N 1000

int IP_Add[N][4],num;  //存放IP地址和个数

利用位移,与,或操作获取子网掩码

int getInterAddr()
{
    int i, j, n,m,len=0;
    for (i = 0; i < 4;i++)
        for (j = 1; j < num;j++)
            if (IP_Add[j][i] != IP_Add[j - 1][i])    //若是和上一个地址不同,则跳出
                goto Next;
Next:    //上面两个for获取的是IP相同的数据组,下面获取不同组的相同位数
    n = m = IP_Add[j - 1][i];
    for (j = 1; j < num; j++)
        n &= IP_Add[j][i],m|=IP_Add[j][i];

    for (int k = 0; k < i; k++)    //开始打印部分网络号
        printf("%d.", IP_Add[0][k]);
    //对n,m做右移操作,获取完整网络号
    while (n != m)    //比较n,m获取相同位数
    {
        n >>= 1, m >>= 1;
        len++;    //len记录的是不同位数
    }
    printf("%d\n", n<<=len);    //记得将n右移回去
    //获取相同位数长度
    return i*8+8-len;
}

根据网络号获取的位数来获取子网掩码

void getSubAddr(int len)
{
    int n;
    for (int i = 0; i < len / 8; i++)
        printf("255.");
    n = 255 - ((int)pow(2.0, (double)(8 - len % 8)) - 1);
    printf("%d", n);
    for (int i = len / 8+1; i < 4; i++)
        printf(".0");
    printf("\n");
}

主函数

void main()
{
    FILE* fp = freopen("data5.in", "r", stdin);
    freopen("data5.out", "w", stdout);
    int l;    //记录子网掩码长度
    
    scanf("%d", &num);    //先读取IP个数
    getchar();
    //再读取所有IP
    for (int i = 0; i < num; i++)
    {
        scanf("%d.%d.%d.%d", &IP_Add[i][0], &IP_Add[i][1], &IP_Add[i][2], &IP_Add[i][3]);
        getchar();
    }

    //开始获取网络地址
    l = getInterAddr();
    //获取子网掩码
    getSubAddr(l);

    freopen("CON", "r", stdin);
    freopen("CON", "w", stdout);
}

全部代码

算法习题---4-5IP网络(Uva1590)_#define算法习题---4-5IP网络(Uva1590)_i++_02
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define N 1000

int IP_Add[N][4],num;

int getInterAddr()
{
    int i, j, n,m,len=0;
    for (i = 0; i < 4;i++)
        for (j = 1; j < num;j++)
            if (IP_Add[j][i] != IP_Add[j - 1][i])    //若是和上一个地址不同,则跳出
                goto Next;
Next:    //上面两个for获取的是IP相同的数据组,下面获取不同组的相同位数
    n = m = IP_Add[j - 1][i];
    for (j = 1; j < num; j++)
        n &= IP_Add[j][i],m|=IP_Add[j][i];

    for (int k = 0; k < i; k++)    //开始打印部分网络号
        printf("%d.", IP_Add[0][k]);
    //对n,m做右移操作,获取完整网络号
    while (n != m)    //比较n,m获取相同位数
    {
        n >>= 1, m >>= 1;
        len++;    //len记录的是不同位数
    }
    printf("%d\n", n<<=len);    //记得将n右移回去
    //获取相同位数长度
    return i*8+8-len;
}

void getSubAddr(int len)
{
    int n;
    for (int i = 0; i < len / 8; i++)
        printf("255.");
    n = 255 - ((int)pow(2.0, (double)(8 - len % 8)) - 1);
    printf("%d", n);
    for (int i = len / 8+1; i < 4; i++)
        printf(".0");
    printf("\n");
}

void main()
{
    FILE* fp = freopen("data5.in", "r", stdin);
    freopen("data5.out", "w", stdout);
    int l;    //记录子网掩码长度
    
    scanf("%d", &num);    //先读取IP个数
    getchar();
    //再读取所有IP
    for (int i = 0; i < num; i++)
    {
        scanf("%d.%d.%d.%d", &IP_Add[i][0], &IP_Add[i][1], &IP_Add[i][2], &IP_Add[i][3]);
        getchar();
    }

    //开始获取网络地址
    l = getInterAddr();
    //获取子网掩码
    getSubAddr(l);

    freopen("CON", "r", stdin);
    freopen("CON", "w", stdout);
}
全部代码