题目:https://vjudge.net/PRoblem/UVA-1590
听说这题用位运算能大幅简化,奈何我不会用。
思路:既然要找个最小范围,自然要知道上限下限,找出最大的ip和最小的ip,然后转换成二进制,比对这两个ip的二进制,找出第一个不相同的位置。在这个位置之前的二进制位最小的不变,最大的赋值为1;在这个位置之后的每个二进制位(包括这个位置),将两ip都赋值为0。再将处理后的这两个ip转换回十进制。那么原来最小的ip就成了网络地址(network address),原来最大的ip就成了子网掩码(network mask)。
语言:c++
#include <cstdio>#include <iostream>#include <cctype>#include <cmath>#include <cstring>using namespace std;struct IP{ int ten[4];//保存十进制形式 char two[4][8];//保存二进制形式,用char类型只是为了省空间};bool isbigger(IP a, IP b)//定义IP大于的比较规则{ int i; for(i=0; i<4; i++) { if(a.ten[i]>b.ten[i]) { return true; } else if(a.ten[i]<b.ten[i]) { return false; } } return false;}bool issmaller(IP a, IP b)//定义IP小于的比较规则{ int i; for(i=0; i<4; i++) { if(a.ten[i]<b.ten[i]) { return true; } else if(a.ten[i]>b.ten[i]) { return false; } } return false;}void change(IP &a)//将十进制转换为二进制{ int i, j, temp; memset(a.two, 0, sizeof(a.two)); for(i=0; i<4; i++) { temp = a.ten[i]; for(j=7; j>=0; j--) { if(temp==0) { break; } a.two[i][j] = temp % 2; temp /= 2; } }}void rechange(IP &a)//将二进制转换为十进制{ memset(a.ten, 0, sizeof(a.ten)); int i, j; for(i=0; i<4; i++) { for(j=0; j<8; j++) { a.ten[i] *= 2; a.ten[i] += a.two[i][j]; } }}void check(IP &minn, IP &maxx)//比对处理函数{ int i, j; bool t=false; for(i=0; i<4; i++) { for(j=0; j<8; j++) { if(t) { minn.two[i][j] = 0; maxx.two[i][j] = 0; } else { if(minn.two[i][j]!=maxx.two[i][j]) { t = true; minn.two[i][j] = 0; maxx.two[i][j] = 0; } else { maxx.two[i][j] = 1; } } } }}void print(IP a){ int i,j; printf("%d.%d.%d.%d/n", a.ten[0], a.ten[1], a.ten[2], a.ten[3]);}int main(){ IP temp, maxx, minn; int i, j, n; while(scanf("%d", &n)!=EOF) { for(i=0; i<n; i++) { for(j=0; j<4; j++) { scanf("%d%*c", &temp.ten[j]); } if(i==0) { maxx = temp; minn = temp; } else { if(isbigger(temp, maxx)) { maxx = temp; } if(issmaller(temp, minn)) { minn = temp; } } } change(minn); change(maxx); check(minn, maxx); rechange(minn); rechange(maxx); print(minn); print(maxx); } return 0;}新闻热点
疑难解答