问题 A: 子网掩码
时间限制: 1 Sec 内存限制: 32 MB
提交: 146 解决: 86[][][]题目描述
子网掩码是用来判断任意两台计算机的IP地址是否属于同一子网络的根据。
最为简单的理解就是两台计算机各自的IP地址与子网掩码进行AND运算后,如果得出的结果是相同的,则说明这两台计算机是处于同一个子网络上的,可以进行直接的通讯。就这么简单。请看以下示例:
运算演示之一:
IP地址 192.168.0.1子网掩码 255.255.255.0转化为二进制进行运算:
IP地址 11010000.10101000.00000000.00000001子网掩码 11111111.11111111.11111111.00000000AND运算:
11010000.10101000.00000000.00000000转化为十进制后为:
192.168.0.0运算演示之二:
IP地址 192.168.0.254子网掩码 255.255.255.0转化为二进制进行运算:
IP地址 11010000.10101000.00000000.11111110子网掩码 11111111.11111111.11111111.00000000AND运算:
11010000.10101000.00000000.00000000转化为十进制后为:
192.168.0.0运算演示之三:
IP地址 192.168.0.4子网掩码 255.255.255.0转化为二进制进行运算:
IP地址 11010000.10101000.00000000.00000100子网掩码 11111111.11111111.11111111.00000000AND运算:
11010000.10101000.00000000.00000000转化为十进制后为:
192.168.0.0通过以上对三组计算机IP地址与子网掩码的AND运算后,我们可以看到它运算结果是一样的,均为192.168.0.0,所以计算机就会把这三台计算机视为在同一子网络。
输入
输入的第一行是本机IP地址;
第二行是子网掩码;第三行是一个整数N,表示后面有N个IP地址;接下来N行:第1个IP地址......第N个IP地址输出
计算并输出N个IP地址是否与本机在同一子网内。对于在同一子网的输出“INNER”,对于在不同子网的输出“OUTER”。
样例输入
192.168.0.1
255.255.255.03192.168.0.2192.168.0.254192.168.1.2样例输出
INNER
INNEROUTER就用了数组, string, 这些简单的存储结构写的. 在转化成二进制那里, 本来想用一个数来存储, 但是如果前面有0, 就会给后面的and运算带来困难. 所以还是用字符串来存储
1 #include2 #include 3 #include 4 using namespace std; 5 6 void binary(int num,int start,int *bin); 7 //将数转化为二进制 8 int *translateIP(string s); 9 //把string转化为二进制数 10 int dicimal(int num); 11 //将二进制转换为十进制 12 string AND(int *IP,int *subnum); 13 //与子网掩码AND运算之后转化为10进制并加成一个数 14 15 void binary(int num,int start,int *bin) //将数转化为二进制,除二倒取余(倒着放) 16 { 17 int locate = start * 8; 18 for (int i=0;i<8;i++) 19 { 20 bin[7 - i + locate] = num % 2; 21 num /= 2; 22 } 23 } 24 25 int *translateIP(string s) //把string转化为二进制数 26 { 27 int num=0,order=0; 28 bool ifnewnum=0; //是否开始了新的数 29 int bin[32]={ 0}; //用来存二进制 30 for(int i=0;s[i]!='\0';i++) 31 { 32 if(s[i]=='.') 33 { 34 ifnewnum=1; 35 continue; 36 } 37 if(ifnewnum) 38 { 39 binary(num, order++,bin); //一个数取完就转换成二进制存入 40 num=0; 41 } 42 num=num*10+s[i]-'0'; 43 ifnewnum=0; 44 } 45 binary(num,order,bin); 46 return bin; 47 } 48 49 50 int dicimal(int num) //将二进制转换为十进制 51 { 52 int temp,dicimalnumber=0; 53 for (int i=0;num != 0;i++) 54 { 55 temp = num % 10; 56 dicimalnumber+=temp*pow(2,i); 57 num /= 10; 58 } 59 return dicimalnumber; 60 } 61 62 string AND(int *IP,int *subnum) //与子网掩码AND运算 63 { 64 int num; 65 string s; 66 for(int i=0;i<32;i++) 67 { 68 num=IP[i]&subnum[i]; 69 s+= char('0' + num); 70 } 71 return s; //虽然题目要求转化为十进制再比较,但可以直接用二进制形式判断 72 } 73 74 int main() 75 { 76 string IP,subnet_mask; //存原始IP和掩码 77 cin>>IP>>subnet_mask; 78 79 int IPnum[32]; 80 memcpy(IPnum, translateIP(IP), sizeof(IPnum)); //将string转换成二进制数存入IPnum 81 int subnum[32]; 82 memcpy(subnum, translateIP(subnet_mask), sizeof(subnum));//将string转换成二进制数存入subnum 83 string andIP= AND(IPnum,subnum),andother; //AND运算之后,用一个字符串存起来 84 85 int N; //接下来有N个IP 86 cin>>N; 87 string other; //存别的IP 88 for(int i=0;i >other; 91 int othernum[32]; 92 memcpy(othernum, translateIP(other), sizeof(othernum)); 93 94 andother=AND(othernum,subnum); //求出每个IP在与子网掩码and之后的值 95 if(andother==andIP) 96 cout<<"INNER"<