POJ 2788 ipnetworks 计算机网络相关知识
?
?
今天剛好考完計算機網(wǎng)絡,剛好復習下IP和子網(wǎng)掩碼的相關(guān)知識。
?
子網(wǎng)掩碼:
子網(wǎng)掩碼是子網(wǎng)劃分的依據(jù),它跟IP地址一樣,長度也是32位,點分十進制表示,每部分0~255,但是跟IP地址不同的是,子網(wǎng)掩碼只能由連續(xù)的1和0組成,也就是說,把這32位從任意位置分開,左邊只能全是1,右邊只能全是0。比如11111111.11111111.11111111.11111000(255.255.255.248)就是合法的子網(wǎng)掩碼,而11000000.10101000.00000001.00000000(192.168.1.0)就不合法。
題意:
給定多個ip,求出這些ip的子網(wǎng)掩碼,和在這個子網(wǎng)掩碼下的最有效的ip,其實就是最小ip。
注意給的多個ip已是同一網(wǎng)段下,所以有效ip的前面就是這些ip的共同值,后面全是0.
思路:
給定兩個IP,假設其子網(wǎng)掩碼二進制有x個連續(xù)的1,則如果這兩個IP的二進制前x位對應相等,那么這兩個IP就屬于同一網(wǎng)段,也就是屬于同一個子網(wǎng)。
如果給定一個子網(wǎng)掩碼和一個IP,就可以求出這個IP所在子網(wǎng)的最小IP,方法是將IP的二進制與子網(wǎng)掩碼的二進制進行按位與運算,原理是,子網(wǎng)掩碼為1的二進制位,要求子網(wǎng)內(nèi)所有IP的這一位必須全部相等,而子網(wǎng)掩碼為0的位不作要求,也就是說,給定一個IP,子網(wǎng)內(nèi)最小IP對應的子網(wǎng)掩碼為1的位必須跟給定IP一樣,按位與的時候,給定IP與子網(wǎng)掩碼是1的位按位與后的結(jié)果不變,子網(wǎng)掩碼0的位按位與后為0(恰好是最小),這樣按位與運算結(jié)束后,得到的IP就是子網(wǎng)內(nèi)最小IP
根據(jù)上面所說,這個題只要求出子網(wǎng)掩碼,然后與給定的任意IP進行按位與運算,就可以得到最小IP了。那么現(xiàn)在關(guān)鍵就是求子網(wǎng)掩碼了,既然給定的這一些IP都是一個網(wǎng)段的,那么找到這些IP里的最小IP和最大IP,然后找到這兩個IP的二進制從左往右看哪一位最先出現(xiàn)不同(異或運算可解),就可以知道子網(wǎng)掩碼里有幾個連續(xù)的1,自然就得到子網(wǎng)掩碼了,然后最小IP便迎刃而解。所以這個題其實很簡單,只要了解點IP地址相關(guān)知識即可。
#include <bits/stdc++.h>using namespace std; const int maxip = (1<<10)+10; //對應11111111,11111110,11111100,11111000,11110000,....10000000,00000000依次減去2^0,1,2,3 int tmp[10] = {255, 254, 252, 248, 240, 224, 192, 128, 0}; int main() {freopen("in.txt","r",stdin); // freopen("ip.out","w",stdout);int ip[4][maxip];int n;while(~scanf("%d",&n)){memset(ip, 0, sizeof(ip));int dns[4];int ansip[4];for(int i=0; i<n; i++)scanf("%d.%d.%d.%d",&ip[0][i], &ip[1][i], &ip[2][i], &ip[3][i]);for(int i=0; i<4; i++){int dif_cur=0, x, j;sort(ip[i], ip[i]+n);int Max = ip[i][n-1];int Min = ip[i][0];//這里可以優(yōu)化for(j=1; j<=8; j++) {if(Max%2 != Min%2)dif_cur = j;//從低位向高位移動,在每位判斷當前位是否相同Max = Max>>1;Min = Min>>1;}//求出這一段的子網(wǎng)掩碼dns[i] = tmp[dif_cur];//最小IP//由這一段的子網(wǎng)掩碼隨便對一個ip(反正都是一個網(wǎng)段)與或運算,只有與1得1,與0會得ip原來的數(shù)位即0//注意子網(wǎng)掩碼和最小的ip不同就是ip在這個網(wǎng)段下,即這個網(wǎng)段的前x個數(shù)位都是相同的,子網(wǎng)掩碼在這前x個都是1ansip[i] = dns[i] & ip[i][1];//這個ip是隨便的,只要是這一段的就行,即一維是i }for(int i=0; i<4; i++){if(dns[i] != ((1<<8)-1) ){for(i = i+1; i<4; i++){dns[i] = 0;dns[i] = 0;}break;}}printf("%d.%d.%d.%d\n",ansip[0], ansip[1], ansip[2], ansip[3]);printf("%d.%d.%d.%d\n", dns[0], dns[1], dns[2], dns[3]);}return 0; } View Code?
轉(zhuǎn)載于:https://www.cnblogs.com/zhangmingzhao/p/7256583.html
總結(jié)
以上是生活随笔為你收集整理的POJ 2788 ipnetworks 计算机网络相关知识的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何使用 backupninja 来备份
- 下一篇: Oracle浅谈第六回