UVa 1590 - IP Networks
题意:
可以用一个网络地址和一个子网掩码描述一个子网(即连续的IP地址范围)。其中子网掩码包含32个二进制位,前32-n位为1,后n位为0,网络地址的前32-n位任意,后n位为0。所有前32-n位和网络地址的IP都属于此网络。题目要求输入m个IP地址,求对应的网络地址和子网掩码。
解题思路:
用数组分别记录输入IP地址中的四位,排序后将最小值和最大值转换成二进制,逐位比较即可得出相同位数n。
具体实现上我是写了binary和decimal两个函数来实现二进制和十进制的转换,数组a,b,c,d分别存的是ip(min),ip(max),address,mask的二进制表示,对数组a,b进行逐位比对求出n。address的前32-n位和a相同,后n位为0;mask前32-n位为1,后n位为0,然后转换成十进制输出就好。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
void binary(int a,int s[]);
int decimal(int s[]);
int main(void){
int n,i,t,address[4],mask[4],ip[4][1005],a[32],b[32],c[32],d[32];
while(~scanf("%d",&n)){
for(i=0;i<n;i++)
scanf("%d.%d.%d.%d",&ip[0][i],&ip[1][i],&ip[2][i],&ip[3][i]);
for(i=0;i<4;i++) sort(ip[i],ip[i]+n);
for(i=0;i<4;i++)
{
binary(ip[i][0],a+8*i);
binary(ip[i][n-1],b+8*i);
}
for(i=0;i<32;i++) if(a[i]!=b[i]) break;
t=32-i;
for(i=0;i<32;i++)
{
if(i<32-t) {c[i]=a[i];d[i]=1;}
else {c[i]=0;d[i]=0;}
}
for(i=0;i<4;i++)
{
address[i]=decimal(c+i*8);
mask[i]=decimal(d+i*8);
}
printf("%d.%d.%d.%d\n",address[0],address[1],address[2],address[3]);
printf("%d.%d.%d.%d\n",mask[0],mask[1],mask[2],mask[3]);
}
return 0;
}
void binary(int a,int s[]){
int i=7;
while(a>0){
s[i--]=a%2;
a/=2;
}
if(i>=0){
for(;i>=0;i--)
s[i]=0;
}
}
int decimal(int s[]){
int i,n=0,t=1;
for(i=7;i>=0;i--)
{
if(s[i]) n+=t;
t*=2;
}
return n;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。