POJ1753-位操作

Flip Game
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 11333 Accepted: 4818

Description

Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 squares. One side of each piece is white and the other one is black and each piece is lying either it's black or white side up. Each round you flip 3 to 5 pieces, thus changing the color of their upper side from black to white and vice versa. The pieces to be flipped are chosen every round according to the following rules: 
  1. Choose any one of the 16 pieces. 
  2. Flip the chosen piece and also all adjacent pieces to the left, to the right, to the top, and to the bottom of the chosen piece (if there are any).

Consider the following position as an example: 

bwbw 
wwww 
bbwb 
bwwb 
Here "b" denotes pieces lying their black side up and "w" denotes pieces lying their white side up. If we choose to flip the 1st piece from the 3rd row (this choice is shown at the picture), then the field will become: 

bwbw 
bwww 
wwwb 
wwwb 
The goal of the game is to flip either all pieces white side up or all pieces black side up. You are to write a program that will search for the minimum number of rounds needed to achieve this goal. 

Input

The input consists of 4 lines with 4 characters "w" or "b" each that denote game field position.

Output

Write to the output file a single integer number - the minimum number of rounds needed to achieve the goal of the game from the given position. If the goal is initially achieved, then write 0. If it's impossible to achieve the goal, then write the word "Impossible" (without quotes).

Sample Input

bwwb
bbwb
bwwb
bwww

Sample Output

4

 

 

 

这是原题。

 

本题如果定义一个数组的话,遍历并判断状态 将是一件费时的事,此时可以想到用位来操作。

先讲一些位操作的基本知识:

int test = 0;

C中,int 有2个字节,C++/Java等语言中有4个字节,而一个字节有8位。

要使test的第一位变成1,则可做一个或运算:test | 1, 第二位变成1,则可这样:test | (1 << 1), 第三位变1,则:test | (1 << 2)。把某位变成0可以用与、非运算,如把第三位变成0,则test & ~(1 << 2) 。可以写一个程序试试:

 

#include<iostream>
using namespace std;

int main()
{
	int a = 1, b = 7; //7用2进制表示是111
	b &= ~(a <<2);
	cout<<b<<endl; //输出结果为3,用2进制表示是11
	return 0;
}

 要把两个数的各个位合并(就是有1即1),可用或运算,给一个示例:

 

	int a = 5, b = 3;
	a |= b;
	cout<<a<<endl; //答案7

 把两个数的各个位相减,用抑或或运算,示例:

 

	int a = 5, b = 3;
	a ^= b;
	cout<<a<<endl; //答案:6

 ……之后还遇到什么位运算再补充。。。

 

本题 可用16位来表示各个状态,两位一个,用1来表示black,0表示white。则65536是全black的情况,0是全白的情况,这样的话,要判断是否已经得出结果时,就不用遍历16个元素了!!!

如本题:

bwwb

bbwb

bwwb

bwww

状态值为6585,计算方法为

1*2^0+0*2^1+0*2^2..1*2^12+0*2^13..=6585

下面是网上摘取的一段代码,呵呵,写得比我的好,转此来学习。

 

在此基础上进行BFS搜索,首先理解一点,先点(0,0)再点(0,1)与先点(0,1)再点(0,0)对结果不造成任何影响.因此遍历棋盘的16个位置,将每次点击后的状态id利用树状结构保存.如:

                                  6585

                               /     |      \  ...

                           (0,0) (0,1)  (0,2)

                            /        |         \  ...

                         6568   6553   6646

                      ...............................

对此树进行BFS搜索,将id为0(全白)或65535(全黑)的时候则搜索成功,输出树的高度,否则输出"Impossible".

为了提高搜索效率,采用位运算,如果想将整数的二进制某一位翻转可采用id^=(1<<x)(x代表要翻转的位置)


 

#include "assert.h"
#include <iostream>
#include <queue>
using namespace std;

const int MAX_STATE = 65536;
const int ALL_WHILE_STATE = 0;
const int ALL_BLACK_STATE = 65535;
const int WIDTH_OF_BOARD = 4;
const int SIZE_OF_BOARD = WIDTH_OF_BOARD * WIDTH_OF_BOARD; // 4 * 4

int ConvertPieceColorToInt(char color)
{
    switch(color)
    {
    case 'b':
        return 1;
    case 'w':
        return 0;
    }
}

int FlipPiece(int state_id, int position)
{
    state_id ^= (1 << position);

    // up
    if(position - 4 >= 0)
        state_id ^= (1 << (position - 4));
    // down
    if(position + 4 < SIZE_OF_BOARD)
        state_id ^= (1 << (position + 4));
    // left
    if(position % 4 != 0)
        state_id ^= (1 << (position - 1));
    // right
    if(position % 4 != 3)
        state_id ^= (1 << (position + 1));

    return state_id;
}

int main()
{
    int current_state_id = 0;
    int state[MAX_STATE];
    queue<int> search_queue;

    memset(state, -1, sizeof(state));

    char color;

    for(int i = 0; i < SIZE_OF_BOARD; ++i)
    {
        cin >> color;
        current_state_id += ConvertPieceColorToInt(color) << i;
    }

    if(current_state_id == ALL_WHILE_STATE
        || current_state_id == ALL_BLACK_STATE)
    {
        cout << "0" << endl;
        return 0;
    }

    state[current_state_id] = 0;
    search_queue.push(current_state_id);

    int next_state_id;

    while(!search_queue.empty())
    {
        current_state_id = search_queue.front();
        search_queue.pop();

        for(int i = 0; i < SIZE_OF_BOARD; ++i)
        {
            next_state_id = FlipPiece(current_state_id, i);
            if(next_state_id == ALL_WHILE_STATE
                || next_state_id == ALL_BLACK_STATE)
            {
                cout << state[current_state_id] + 1 << endl;
                return 0;
            }
            assert(next_state_id < MAX_STATE);
            if(state[next_state_id] == -1 /* not visited */)
            {
                state[next_state_id] = state[current_state_id] + 1;
                search_queue.push(next_state_id);
            }
        }
    }

    cout << "Impossible" << endl;
    return 0;
}
数据心机房是现代信息技术的核心设施,它承载着企业的重要数据和服务,因此,其基础设计与规划至关重要。在制定这样的方案时,需要考虑的因素繁多,包括但不限于以下几点: 1. **容量规划**:必须根据业务需求预测未来几年的数据处理和存储需求,合理规划机房的规模和设备容量。这涉及到服务器的数量、存储设备的容量以及网络带宽的需求等。 2. **电力供应**:数据心是能源消耗大户,因此电力供应设计是关键。要考虑不间断电源(UPS)、备用发电机的容量,以及高效节能的电力分配系统,确保电力的稳定供应并降低能耗。 3. **冷却系统**:由于设备密集运行,散热问题不容忽视。合理的空调布局和冷却系统设计可以有效控制机房温度,避免设备过热引发故障。 4. **物理安全**:包括防火、防盗、防震、防潮等措施。需要设计防火分区、安装烟雾探测和自动灭火系统,设置访问控制系统,确保只有授权人员能进入。 5. **网络架构**:规划高速、稳定、冗余的网络架构,考虑使用光纤、以太网等技术,构建层次化网络,保证数据传输的高效性和安全性。 6. **运维管理**:设计易于管理和维护的IT基础设施,例如模块化设计便于扩展,集监控系统可以实时查看设备状态,及时发现并解决问题。 7. **绿色数据心**:随着环保意识的提升,绿色数据心成为趋势。采用节能设备,利用自然冷源,以及优化能源管理策略,实现低能耗和低碳排放。 8. **灾难恢复**:考虑备份和恢复策略,建立异地灾备心,确保在主数据心发生故障时,业务能够快速恢复。 9. **法规遵从**:需遵循国家和地区的相关法律法规,如信息安全、数据保护和环境保护等,确保数据心的合法运营。 10. **扩展性**:设计时应考虑到未来的业务发展和技术进步,保证机房有充足的扩展空间和升级能力。 技术创新在数据心机房基础设计及规划方案扮演了重要角色。例如,采用虚拟化技术可以提高硬件资源利用率,软件定义网络(SDN)提供更灵活的网络管理,人工智能和机器学习则有助于优化能源管理和故障预测。 总结来说,一个完整且高效的数据心机房设计及规划方案,不仅需要满足当前的技术需求和业务目标,还需要具备前瞻性和可持续性,以适应快速变化的IT环境和未来可能的技术革新。同时,也要注重经济效益,平衡投资成本与长期运营成本,实现数据心的高效、安全和绿色运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值