• 【POJ1753】Flip Game


    题目传送门

    本题知识点:深度优先搜索 + 暴力枚举 + 回溯

    本题题意比较简单,要求把棋盘的棋子翻成同一颜色的,如果可以就输出最少步数,否则“Impossible”。

    样例4步最快的就是把棋子都翻成white('w'),此时我犯了一个严重的错误。

    在草稿纸上我的四步是这样走的:

    第一步:翻 (1,1)

    第二步:翻 (1,3)

    第三步:翻 (2,2)

    第四步:翻 (2,4)

    //   1 2 3 4
    // 1 b w w b
    // 2 b b w b
    // 3 b w w b
    // 4 b w w w
    

    于是我一整天的思路是:遍历16个点,然后每次遍历时重新从(1,1)这个点开始搜。

    喵喵喵?那这样1s真的可以吗?

    当然不行!

    在花了一上午的时间后,我终于按耐不住看了其他大牛的题解,才发现自己以上的思路重复了。对!以上四步,无论哪步先走,效果都是一样的!

    因此,我们只需要从 (1,1) 搜到 (4,4) 即可

    搜的时候有两种状态,翻与不翻

    例如:样例中, (1,1) 是翻了的,接着到 (2,2) 才翻,换句话说,(1,2) (1,3) (1,4) (2,1) 这些点都是没有翻的。

    要注意的一点是,翻的棋子未必是正确的棋子,因此我们翻完之后还需要把它翻回原状(这就是回溯思想)

    最后我们每次都查一下是否都是黑棋或者是白棋都行了。

    (附上AC代码以及自己之前写的又长又臭的代码)

    //// POJ 1753
    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    char chess[10][10];
    int ans = 0x3f3f3f3f, cnt;
    
    void init(){
        for(int i = 0; i < 10; i++){
            for(int j = 0; j < 10; j++){
                chess[i][j] = 'a';
            }
        }
    }
    
    bool check(){
        bool can = true;
        char ch = chess[1][1];
        for(int i = 1; i <= 4; i++){
            for(int j = 1; j <= 4; j++){
                if(ch != chess[i][j]){
                    can = false;
                    return can;
                }
            }
        }
        return can;
    }
    
    void turn(int h, int w){ 
        // mid
        if(chess[h][w] == 'b') chess[h][w] = 'w';
        else chess[h][w] = 'b';
        // up
        if(chess[h + 1][w] == 'b') chess[h + 1][w] = 'w';
        else if(chess[h + 1][w] == 'w') chess[h + 1][w] = 'b';
        // right
        if(chess[h][w + 1] == 'b') chess[h][w + 1] = 'w';
        else if(chess[h][w + 1] == 'w') chess[h][w + 1] = 'b';
        // down
        if(chess[h - 1][w] == 'b') chess[h - 1][w] = 'w';
        else if(chess[h - 1][w] == 'w') chess[h - 1][w] = 'b';
        // left
        if(chess[h][w - 1] == 'b') chess[h][w - 1] = 'w';
        else if(chess[h][w - 1] == 'w') chess[h][w - 1] = 'b';
    }
    
    void dfs(int h, int w, int cnt){
        if(check()){ // check
            if(cnt < ans) ans = cnt;
            return ;
        }
        if(h == 5) return ;
    
        // 翻它
        turn(h, w); // change
        if(w == 4) dfs(h + 1, 1, cnt + 1); // 换行
        else dfs(h, w + 1, cnt + 1);
        turn(h, w); // back 翻回来
    
        // 不翻不翻
        if(w == 4) dfs(h + 1, 1, cnt);
        else dfs(h, w + 1, cnt);
    }
    int main()
    {
        init();
        for(int i = 1; i <= 4; i++){
            scanf("%s", chess[i] + 1);
        }
        dfs(1, 1, 0);
        if(ans != 0x3f3f3f3f) printf("%d
    ", ans);
        else printf("Impossible
    ");
        return 0;
    }
    //#include<iostream>
    //#include<cstdio>
    //#include<cstring>
    //using namespace std;
    //
    //char first[10][10];
    //char chess[10][10];
    //bool take[10][10];
    //int ans = 0x3f3f3f3f, cnt;
    //int black, white, B, W;
    //
    //void init(){
    //    for(int i = 0; i <= 5; i++){
    //        for(int j = 0; j <= 5; j++){
    //            first[i][j] = 'a';
    //        }
    //    }
    //}
    //
    //void show(){
    //    for(int i = 1; i <= 4; i++){
    //        printf("%s
    ", chess[i] + 1);
    //
    //    } putchar('
    ');
    //}
    //
    //void save(){
    //    for(int i = 0; i <= 5; i++){
    //        for(int j = 0; j <= 5; j++){
    //            chess[i][j] = first[i][j];
    //        }
    //    }
    //}
    //
    //bool check(){
    //    bool can = true;
    //    char ch = chess[1][1];
    //    for(int i = 1; i <= 4; i++){
    //        for(int j = 1; j <= 4; j++){
    //            if(ch != chess[i][j]){
    //                can = false;
    //            }
    //        }
    //    }
    //    return can;
    //}
    //
    //void turn(int h, int w){
    //    // up
    //    if(chess[h + 1][w] == 'b') chess[h + 1][w] = 'w';
    //    else if(chess[h + 1][w] == 'w') chess[h + 1][w] = 'b';
    //    // right
    //    if(chess[h][w + 1] == 'b') chess[h][w + 1] = 'w';
    //    else if(chess[h][w + 1] == 'w') chess[h][w + 1] = 'b';
    //    // down
    //    if(chess[h - 1][w] == 'b') chess[h - 1][w] = 'w';
    //    else if(chess[h - 1][w] == 'w') chess[h - 1][w] = 'b';
    //    // left
    //    if(chess[h][w - 1] == 'b') chess[h][w - 1] = 'w';
    //    else if(chess[h][w - 1] == 'w') chess[h][w - 1] = 'b';
    //}
    //
    //void back(int h, int w){
    //    // up
    //    if(chess[h + 1][w] == 'b') chess[h + 1][w] = 'w';
    //    else if(chess[h + 1][w] == 'w') chess[h + 1][w] = 'b';
    //    // right
    //    if(chess[h][w + 1] == 'b') chess[h][w + 1] = 'w';
    //    else if(chess[h][w + 1] == 'w') chess[h][w + 1] = 'b';
    //    // down
    //    if(chess[h - 1][w] == 'b') chess[h - 1][w] = 'w';
    //    else if(chess[h - 1][w] == 'w') chess[h - 1][w] = 'b';
    //    // left
    //    if(chess[h][w - 1] == 'b') chess[h][w - 1] = 'w';
    //    else if(chess[h][w - 1] == 'w') chess[h][w - 1] = 'b';
    //}
    //
    //void solve_white(int h, int w){
    //    cnt++;
    //    // mid
    //    chess[h][w] = 'w';
    //    white++; black--;
    //    turn(h, w);
    //
    //    if(check()){
    //        if(cnt < ans) ans = cnt;
    ////        show();
    //        return ;
    //    }
    //
    //    for(int i = 1; i <= 4; i++){
    //        for(int j = 1; j <= 4; j++){
    //            if(chess[i][j] == 'b' && !take[i][j]){
    //                take[i][j] = true;
    //                solve_white(i, j);
    //                take[i][j] = false;
    //                cnt--;
    //                chess[i][j] = 'b';
    //                back(i, j);
    //            }
    //        }
    //    }
    //}
    //
    //void solve_black(int h, int w){
    //    cnt++;
    //    // mid
    //    chess[h][w] = 'b';
    //    black++; white--;
    //    turn(h, w);
    //
    //    if(check()){
    //        if(cnt < ans) ans = cnt;
    ////        show();
    //        return ;
    //    }
    //
    //    for(int i = 1; i <= 4; i++){
    //        for(int j = 1; j <= 4; j++){
    //            if(chess[i][j] == 'w' && !take[i][j]){
    //                take[i][j] = true;
    //                solve_white(i, j);
    //                take[i][j] = false;
    //                cnt--;
    //                chess[i][j] = 'w';
    //                back(i, j);
    //            }
    //        }
    //    }
    //}
    //
    //int main()
    //{
    //    init();
    //    for(int i = 1; i <= 4; i++){
    //        scanf("%s", first[i] + 1);
    //    }
    //
    //    save();
    //    if(check()){
    //        printf("%d
    ", 0);
    //        return 0;
    //    }
    //
    //    // turn white is all
    //    for(int i = 1; i <= 4; i++){
    //        for(int j = 1; j <= 4; j++){
    //            if(chess[i][j] == 'b'){
    //                cnt = 0;
    //                black = B; white = W;
    //                take[i][j] = true;
    //                solve_white(i, j);
    //                memset(take, false, sizeof(take));
    //                save();
    ////                printf("i:%d j:%d ans:%d
    ", i, j, ans);
    //            }
    //        }
    //    }
    //    printf("white %d
    ", ans);
    //
    //    save();
    //    memset(take, false, sizeof(take));
    //    // turn black is all
    //    for(int i = 1; i <= 4; i++){
    //        for(int j = 1; j <= 4; j++){
    //            if(chess[i][j] == 'w'){
    //                cnt = 0;
    //                black = B; white = W;
    //                take[i][j] = true;
    //                solve_black(i, j);
    //                memset(take, false, sizeof(take));
    //                save();
    ////                printf("i:%d j:%d ans:%d
    ", i, j, ans);
    //            }
    //        }
    //    }
    //
    //    if(ans == 0x3f3f3f3f) printf("Impossible
    ");
    //    else printf("%d
    ", ans);
    //
    //    return 0;
    //}
    
    
  • 相关阅读:
    layui table中省略号展开,弹框拖动会错位问题
    layui table分页 page为false时,limit问题
    layui 表格在排序之后没有重新渲染问题
    基于jQuery的控件:弹框
    layui layer弹框中表格的显示
    layui select使用问题
    页面强制横屏
    linux下常用命令
    文字超出省略号显示
    Web Notification简单实现桌面消息通知(右下角提示)
  • 原文地址:https://www.cnblogs.com/Ayanowww/p/11526684.html
Copyright © 2020-2023  润新知