CDZSC 美图新生赛题F 1583 网络号与主机号 题解

1583: 网络号与主机号

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 27   Solved: 14
[ Submit][ Status][ Web Board]

Description

在计算机网络通讯中,IP地址是非常重要的概念。IP地址是一个32位的无符号的整数。为了方便表示,将IP用.号将这32位数分为4个部分,每个部分8位,并把二进制转化为十进制表示,这就是我们常见到的IP的格式。
例如:
00000011100000001111111111111111->00000011.10000000.11111111.11111111->3.128.255.255
IP地址可以划分为网络号和主机号两个部分。划分需要给定一个网络掩码。
网络掩码是特殊的32位无符号整数,即从左往右前n位是连续的1剩下的是0,例如255.255.255.128,为了简化通常将网络掩码书写为n(1<=n<=30)。
IP地址可以划分为网络号和主机号的方法是根据网络掩码n:IP地址的前n位保留,剩下的全为0,得到的32位无符号整数为网络号;IP地址的前n位变为0,剩下的保留,得到的32位无符号整数为主机号。
例如:3.128.255.255/25 (25为上述的n,即网络掩码的简写)
3.128.255.255/25->00000011.10000000.11111111.11111111
                                   00000011.10000000.11111111.10000000 ->3.128.255.128 这就是网络号
                                   00000000.00000000.00000000.01111111 -> 0.0.0.127 这就是主机号

现在给定一个带有网络掩码的IP,请求出这个IP的网络号和主机号。

Input

 输入数据有多组,第一行为一个整数t,表示数据的组数。每组数据占一行,为带有网络掩码的IP,格式为a.b.c.d/n,a,b,c,d,n为非负整数,0<=a,b,c,d<=255,1<=n<=30

Output

 每组数据输出占一行,包含网络号和主机号。用空格隔开。

Sample Input

2192.168.1.1/243.128.255.255/25

Sample Output

192.168.1.0 0.0.0.1
3.128.255.128 0.0.0.127
此题只需要把IP地址按照A.B.C.D/Hide 的格式输入就好,然后转化为二进制存进数组,按要求把指定位数置零再重
新转为10进制输出即可。
Code:
#include <stdio.h>
void exgto(char two[], int start, int target);
int exgback(char two[], int start);
int main() {
    int n;
    scanf("%d", &n);
    while (n--) {
        int a, b, c, d, hide;
        char two[35], host[35], mask[35];
        for (int i = 0; i < 32; i++) {
            two[i] = 0;
        }
        scanf("%d.%d.%d.%d/%d", &a, &b, &c, &d, &hide);
        exgto(two, 7, a);
        exgto(two, 15, b);
        exgto(two, 23, c);
        exgto(two, 31, d);
        for (int i = 0; i < 32; i++) {
            host[i] = two[i];
            mask[i] = two[i];
        }
        for (int i = hide; i < 32; i++) {
            host[i] = 0;
        }
        for (int i = 0; i < hide; i++) {
            mask[i] = 0;
        }
        int back;
        back = exgback(host, 0);
        printf("%d.", back);
        back = exgback(host, 8);
        printf("%d.", back);
        back = exgback(host, 16);
        printf("%d.", back);
        back = exgback(host, 24);
        printf("%d ", back);
        back = exgback(mask, 0);
        printf("%d.", back);
        back = exgback(mask, 8);
        printf("%d.", back);
        back = exgback(mask, 16);
        printf("%d.", back);
        back = exgback(mask, 24);
        printf("%d\n", back);
    }
    return 0;
}
void exgto(char two[], int start, int target) {
    int saves = start;
    while (target != 0) {
        two[start] = target % 2;
        target = target / 2;
        start--;
    }
}
int exgback(char two[], int start) {
    int back = 0, d2 = 128;
    for (int i = 0; i < 8; i++) {
        back += two[start] * d2;
        d2 = d2 / 2;
        start++;
 }

本人新手,有任何关于改进代码的建议欢迎提出!感激不尽!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值