poj 2799 IP Networks 模拟 位运算

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;
}
时间: 2024-10-15 06:51:07

poj 2799 IP Networks 模拟 位运算的相关文章

poj 2799 IP Networks 模拟

题意: 给一些ip,求包括他们的最小网络(网络号+子网掩码). 分析: 关键是找到从高位到低位从哪位开始不同. 代码: //poj 2799 //sep9 #include <iostream> using namespace std; typedef long long ll; ll vis[40]; void print(ll x) { ll a,b,c,d; d=x%(1<<8); x=x/(1<<8); c=x%(1<<8); x=x/(1<&

poj 2799 IP Networks (模拟/水题)

题目:给你一堆ip,求他们的最小网络地址和网络掩码 思路:找到最大的ip和最小的ip,把他们转化成二进制,从头到尾找二进制位相同的个数,最小网络地址把后面的不同的所有二进制变成0,网络掩码把前面的相同变成一 代码: #include <iostream> #include <cstring> #include <algorithm> #include <cstdio> using namespace std; struct node { char k[35]

POJ 2799 IP Networks

IP Networks Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2159   Accepted: 815 Description Alex is administrator of IP networks. His clients have a bunch of individual IP addresses and he decidedto group all those IP addresses into the

[模拟]位运算实现加减法

1 /* 2 * 单位加:找与+对应的位运算,分析真值表得出是按位异或^ 3 * 进位:可以用<<进行,但是要判断是否存在进位操作,则需要&来判断. 4 * 加的操作执行到不进位为止,代码如下: 5 * 6 */ 7 LL quickadd(int x, int y) { 8 int xr = x ^ y; //加 9 int nd = x & y; //统计进位 10 while(nd) { 11 int xr1 = xr; 12 int nd1 = nd <<

[POJ] 2453 An Easy Problem [位运算]

An Easy Problem Description As we known, data stored in the computers is in binary form. The problem we discuss now is about the positive integers and its binary form. Given a positive integer I, you task is to find out an integer J, which is the min

POJ 1166 The Clocks 位运算与BFS

1.题意:有一组3*3的只有时针的挂钟阵列,每个时钟只有0,3,6,9三种状态:对时针阵列有9种操作,每种操作只对特点的几个时钟拨一次针,即将时针顺时针波动90度,现在试求从初试状态到阵列全部指向0的状态所需要的最小操作数的操作方案: 2.输入输出:输入给出阵列初始状态,0,1,2,3分别表示0,3,6,9:要求输出最快方案的操作序列: 3.分析:IOI 1994的考题,BFS是比较容易想到的方法之一,关键是如何简洁的表示和改变BFS过程中的阵列状态:这里使用位运算的方法:具体如下: 首先一共9

POJ 2777 Count Color(线段树+位运算)

题目链接:http://poj.org/problem?id=2777 Description Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds of problems. Here, we get a new problem. There is a very long board with length L centimeter, L is a

【模拟+递归+位运算】POJ1753-Flip Game

由于数据规模不大,利用爆搜即可.第一次用位运算写的,但是转念一想应该用递归更加快,因为位运算没有剪枝啊(qДq ) [思路] 位运算:时间效率较低(172MS),有些辜负了位运算的初衷.首先将二维数组倒序看作一个二进制数num.我们假设1代表翻转,0代表不翻转,可以发现以下规律:0 xor 1=1,1 xor 1=0;0 xor 0=0,1 xor 0=1,恰巧满足异或运算.我们假设另一个二进制数i∈[0,2^16),通过异或运算就可以模拟出所有清形. 用check和i进行&操作可以求出以哪些位

hdu 3257 Hello World!(位运算 &amp; 模拟)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3257 Hello World! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 476    Accepted Submission(s): 180 Problem Description Your task is to print ...