POJ_1753(位运算)

POJ 1754

Program links: http://poj.org/problem?id=1753

The purpose of writing this blog is to make me remember the bitwise operation.
符号描述运算规则
&两个位都为1时,结果才为1
|两个位都为0时,结果才为0
^异或两个位相同为0,相异为1
~取反0变1,1变0
<<左移各二进位全部左移若干位,高位丢弃,低位补0
>>右移各二进位全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移)

eg:

  1. 判断右起第i位是不是1:(x >> (i - 1)) == 1
  2. 右数第k位取反:x ^ (1 << (k - 1))

附上大牛的位运算详解:
http://blog.csdn.net/morewindows/article/details/7354571
http://www.matrix67.com/blog/archives/263

这题题意大概是选一个把它的上下左右(如果有)和自己翻一下

因为只有两个状态所以选择了二进制然后用位运算

比较坑爹的地方在于不好模拟,这里给出样例的模拟:

1001 1101 1001 1000
0101 0101 1001 1000
1011 0001 1001 1000
1111 1111 1101 1000
1111 1111 1111 1111
4次

顺便我在代码里加上了last数组用来查看结果是怎么得到的,方便得知程序是否正确,代码如下:

c++
#include <iostream>
#include <queue>

using namespace std;

int main()
{
    int k = 0;
    char c;
    for (int i = 0; i < 16; i++) {
        cin >> c;
        if (c == 'b')
            k = k * 2 + 1;
        else if (c == 'w')
            k = k * 2;
    }

    if (k == 0 || k == ((1 << 16) - 1)) {
        cout << "0" << endl;
        return 0;
    }

    queue <int> t, m;
    bool a[1 << 16] = { 0 };
    int last[1 << 16] = { 0 };

    t.push(0);
    m.push(k);
    a[k] = 1;

    while (!t.empty()) {
        for (int i = 15; i >= 0; i--) {
            k = m.front() ^ (1 << i);
            if (i + 4 < 16)
                k = k ^ (1 << (i + 4));
            if (i - 4 >= 0)
                k = k ^ (1 << (i - 4));
            if (i % 4 != 0)
                if (i != 0)
                    k = k ^ (1 << (i - 1));
            if ((i + 1) % 4 != 0)
                if (i != 15)
                    k = k ^ (1 << (i + 1));
            if ((k == 0) || (k == ((1 << 16) - 1))) {
                cout << t.front() + 1 << endl;
                return 0;
            }
            if (!a[k]) {
                t.push(t.front() + 1);
                m.push(k);
                a[k] = 1;
                last[k] = m.front();
            }
        }
        t.pop();
        m.pop();
    }

    cout << "Impossible" << endl;

    return 0;
}

顺便一提:markdown里面的>>是这么打出来的“& g t ; & g t ;”(空格和引号自己去掉)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值