標籤:
poj連結:http://poj.org/problem?id=2799
這題實在是非常的有趣...
寫的時候也非常的開心...
然後就寫跪了...
剛好講了ip地址和子網路遮罩的只是
整個學期的通訊導論我就只有這節課有事沒去結果昨晚把這方面的只是補起來了有種功德圓滿的感覺
network address是前(32-n)隨意 後n位全零
network mask是前(32-n)全一 後n位全零
其次是練習了各種移位操作
我發現移位操作是個非常好用的東西 因為它自填充0
所以對一個位元往右移8位再往左移8位就相當於把最右的八位抹掉 利用這個原理就可以很容易提取出一個數的二進位形式的中間某些位
剔去一個數的二進位形式的中間某些位另一個方法是
用位元運算去並上一個篩
這題我就是用這種方法
然後有一個坑爹的地方就是
對於unsigned int 它的移位的運算元會先對32模數 以至於如果對a執行“a >> 32”它還是a 相當於“a >> 0”(不要問我是怎麼知道的 再次哭暈在廁所T^T
所以這次學習了用位元運算去並上一個篩來取數這一點要學起來
而且貌似對於string類也可用
然後練了練常數的寫法
1ULL表示無符號長整型的常數1
依次類推
此種寫法能有效防止不必要的溢出
(1ULL<<i)-1U表示2^i-1 之所以前面要ULL請看上一段(不要再問我是怎麼知道的了!
然後取個反~ 就可以作為mask的枚舉
然後拿mask和mins或者maxs並一下就得到address了
姿勢太美
最後我想說 “寫跪了就換姿勢”常有奇效
就用你能想到的與現有解法有不小差距的另一種做法去寫
說不定就過了
#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>#include <cmath>#include <set>#include <queue>#include <stack>#include <map>#include <vector>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int, int> P;const int maxn = 70;int main(){ //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); int n; while(scanf("%d", &n) == 1) { unsigned int maxs = 0; unsigned int mins = 0-1; int a, b, c, d; unsigned int e; for(int i = 0; i < n; i++) { scanf("%d.%d.%d.%d", &a, &b, &c, &d); e = ((unsigned int)a << 24) + (b << 16) + (c << 8) + d; if(e < mins) mins = e; if(e > maxs) maxs = e; } unsigned int mask; for (int i = 0; i <= 32; i++) { mask = ~((1ULL<<i)-1U); if ((mins & mask) == (maxs & mask)) break; } unsigned int ans = mins & mask; printf("%u.%u.%u.%u\n", ans >> 24, (ans << 8) >> 24, (ans << 16) >> 24, (ans << 24) >> 24); printf("%u.%u.%u.%u\n", mask >> 24, (mask << 8) >> 24, (mask << 16) >> 24, (mask << 24) >> 24); } return 0;}
poj 2799 IP Networks 類比 位元運算