Uva 1590 IP Networks

本文分享了一道关于子网掩码的编程题解答过程,重点介绍了如何将IPv4地址转换为二进制,并通过对比找到子网划分的边界。文章还讨论了使用指针和无符号整形变量提高代码效率的方法。

题目:略(不会把PDF格式的题目直接转过来,希望有大神可以指教一下)

心得:

1、读题用了很久又到网上搜索了子网掩码的百科才搞懂题目,唯一的思路是只要找出给出的网络地址中二进制位第一位不同的即可,难点是在实现的过程

2、我是把十进制 -> 二进制 -> 通过笨方法输出;网上看到的一种简洁的方法是用无符号整形存储每个32位,这样在二进制 -> 输出时代码会精简很多。(感悟:对二进制、2147483647、4294967295这样的东西要极度敏感,这种东西大部分时候都可以用无符号整形来存储)

3、第一次尝到指针带来的甜味,以后要尽量用指针来写函数,多练习

代码:

#include"stdio.h"
#include"string.h"
struct net{
	int a,b,c,d;
	int ca[33];
}m[1001];
void zhuan(int a,int * p){
	int j=7;
	while(a)
	{
		*(p+j)=a%2;
		a/=2;
		j--;
	}
}//第一次尝试用含指针的函数,指针很神奇,很好用 
void stop(int i){
	for(int j=i;j<32;j++)
		m[0].ca[j]=0;
	int q=0,w=0,e=0,r=0,z[4];
		q=m[0].ca[7]+m[0].ca[6]*2+m[0].ca[5]*4+m[0].ca[4]*8+m[0].ca[3]*16+m[0].ca[2]*32+m[0].ca[1]*64+m[0].ca[0]*128;
		w=m[0].ca[7+8]+m[0].ca[6+8]*2+m[0].ca[5+8]*4+m[0].ca[4+8]*8+m[0].ca[3+8]*16+m[0].ca[2+8]*32+m[0].ca[1+8]*64+m[0].ca[0+8]*128;
		e=m[0].ca[7+16]+m[0].ca[6+16]*2+m[0].ca[5+16]*4+m[0].ca[4+16]*8+m[0].ca[3+16]*16+m[0].ca[2+16]*32+m[0].ca[1+16]*64+m[0].ca[0+16]*128;
		r=m[0].ca[7+24]+m[0].ca[6+24]*2+m[0].ca[5+24]*4+m[0].ca[4+24]*8+m[0].ca[3+24]*16+m[0].ca[2+24]*32+m[0].ca[1+24]*64+m[0].ca[0+24]*128;
	//这里其实可以用函数代替,不过数据比较少的我还是喜欢用傻方法 
	if(i%8==7)
		z[i/8]=254;
	if(i%8==6)
		z[i/8]=252;
	if(i%8==5)
		z[i/8]=248;
	if(i%8==4)
		z[i/8]=240;
	if(i%8==3)
		z[i/8]=224;
	if(i%8==2)
		z[i/8]=192;
	if(i%8==1)
		z[i/8]=128;
	if(i%8==0)
		z[i/8]=0;	
	//判断i在8位中的位置,然后赋值,暂时想不到更好的解决办法 
	for(int j=0;j<i/8;j++)
		z[j]=255;
	for(int j=i/8+1;j<=3;j++)
		z[j]=0;
	printf("%d.%d.%d.%d\n",q,w,e,r);
	printf("%d.%d.%d.%d\n",z[0],z[1],z[2],z[3]);
}
int main()
{
	int n,i,j,f=0;
	while(scanf("%d",&n)!=EOF){f=0;
	memset(m,0,sizeof(m[0])*1001);
	for(i=0;i<n;i++){
		scanf("%d.%d.%d.%d",&m[i].a,&m[i].b,&m[i].c,&m[i].d);
		zhuan(m[i].a,&m[i].ca[0]);zhuan(m[i].b,&m[i].ca[8]);zhuan(m[i].c,&m[i].ca[16]);zhuan(m[i].d,&m[i].ca[24]);
	}
	for(i=0;i<32&&f!=1;i++)			//WA很多次就是因为这里没有加f!=1,最后一位如果出现不同会输出两次结果! 
	{
		for(j=1;j<n&&f!=1;j++)
		{
			if(m[j].ca[i]!=m[j-1].ca[i])
				{stop(i);f=1;}
		}
	}	
	if(i==32&&f!=1)
	{printf("%d.%d.%d.%d\n",m[0].a,m[0].b,m[0].c,m[0].d);printf("255.255.255.255\n");}
	}
}
PS:这题是到目前为止这次集训收获最大的一题,小有成就感!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值