码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 1753

时间:2020-01-31 14:21:40      阅读:52      评论:0      收藏:0      [点我收藏+]

标签:出现   过滤   pac   记录   复杂   set   ble   imp   规划   

题目大意:

有 4x4 的正方形,每个格子要么是黑色,要么是白色,当把一个格子的颜色改变(黑->白或者白->黑)时,其周围上下左右(如果存在的话)的格子的颜色也被反转,问至少反转几个格子可以使 4x4 的正方形变为纯白或者纯黑?

//1753
//动态规划
//Flip Game

#include<iostream>
#include<string>
#include<bitset>

#define MAX 100000

using namespace std;

typedef unsigned short grid;

//翻转格子
//flipPos : 翻转格子的位置;  item: 被翻转的对象
//返回翻转后的grid
grid Flip( int flipPos, grid item )
{
    item ^= (1 << (flipPos-1) );
    if(flipPos > 4){
        item ^= (1 << (flipPos-4-1) );
    }
    if(flipPos % 4 != 1){
        item ^= (1 << (flipPos-1-1) );
    }
    if(flipPos % 4 != 0){
        item ^= (1 << (flipPos+1-1) );
    }
    if(flipPos < 13){
        item ^= (1 << (flipPos+4-1) );
    }

    return item;
}



int main(int argc, char *argv[])
{
    string str;
    string lineStr;
    grid gridOne = 0;
    int i;

    //input
    i = 0;
    while( i++ < 4 ){
        cin >> lineStr;
        str += lineStr;
    }

    //change string to unsigned shor
    //b->1, w->0
    i = 15;
    for( string::iterator c = str.begin();  c != str.end();  c++ ){
        if( *c == 'b' ){
            gridOne |= (1 << i);
        }
        i--;
    }

    if( gridOne == 0 ||  gridOne == 0xffff ){
        cout << 0 << endl;
        return 0;
    }
    

    //calculate time
    typedef struct Table{
        grid gridItem;
        int step;   //第几次翻转
        int pos;
    }Table;

    Table table[MAX];
    bool flags[MAX] = {false};  //对已经出现过的情况做标记;没有这个可能会出现死循环

    table[0].gridItem = gridOne;
    table[0].pos = -1;
    table[0].step = 0;
    flags[gridOne] = true;  

    grid item;
    int current = 0;    //当前k情况
    int capacity = 1;   //所有可能情况的总数

    //test
    //cout << str << endl;
    //cout << bitset<sizeof(grid)*8>(gridOne) << endl;
    //cout << "test end";
    

    while( current != capacity ){
        item = table[current].gridItem;

        //位置从1开始
        for(i=1; i<17; i++){
            if( table[current].pos != i ){
                grid newItem = Flip(i, item);

                if( flags[newItem] == false ){
                    table[capacity].gridItem = newItem;
                    table[capacity].pos = i;
                    table[capacity].step = table[current].step + 1;
                    flags[newItem] = true;

                    if( table[capacity].gridItem == 0 || table[capacity].gridItem == 0xffff ){
                        cout << table[capacity].step << endl;
                        return 0;
                    }

                    capacity++;
                }
            }
        }
        current++;
    }   

    cout << "Impossible" << endl;
    return 0;
}

下面说说自己的收获

  • 创建结构数组比结构体里包含数组要方便
  • 这里使用线性存储树结构
  • 在使用动态规划时,不仅仅要注意“存储表”的创建,同时更重要的是去除重复情况,这题使用flags标记来过滤重复的grid。这题不过滤重复情况可能会陷入死循环。
  • 这题通过结构体来记录翻转次数step,这种方法虽然空间消耗大,但是写法简单。如果只用一个变量记录翻转次数step,写法复杂,考虑的逻辑情况较多。

POJ 1753

标签:出现   过滤   pac   记录   复杂   set   ble   imp   规划   

原文地址:https://www.cnblogs.com/friedCoder/p/12245105.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!