zoukankan      html  css  js  c++  java
  • POJ 2286 The Rotation Game(DFS + 迭代加深)

    题意:

    移动八根线中任一根,移法为头的数移到线的尾,其它的数向头进一位。求最少要移多少次才能使中间的八个数相等。

    思路:

    1. 本题最重要的是如何去设计状态的转移,这里采用了一些静态移动的方法,使代码写起来简洁易懂;

    2. 剩下的就是使用 IDA* 去进行搜索了,每次对 bound 适当的放缩,直到方块中间的 8 个数相等为止;

    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int dir[8][7] = {
        0,2,6,11,15,20,22,
        1,3,8,12,17,21,23,
        10,9,8,7,6,5,4,
        19,18,17,16,15,14,13,
        23,21,17,12,8,3,1,
        22,20,15,11,6,2,0,
        13,14,15,16,17,18,19,
        4,5,6,7,8,9,10};
    
    const int aim[8] = {6,7,8,11,12,15,16,17};
    const int rev[8] = {5,4,7,6,1,0,3,2};
    int square[30], Q[30], qc;
    
    void change(int r) {
        int t0 = square[dir[r][0]];
        for (int i = 0; i < 6; i++)
            square[dir[r][i]] = square[dir[r][i+1]];
        square[dir[r][6]] = t0;
    }
    
    int getremainder() {
        int a = 0, b = 0, c = 0;
        for (int i = 0; i < 8; i++) {
            if (square[aim[i]] == 1) a += 1;
            else if (square[aim[i]] == 2) b += 1;
            else if (square[aim[i]] == 3) c += 1;
        }
        int t = max(a, max(b, c));
        return 8 - t;
    }
    
    int bound;
    bool succ;
    
    int dfs(int step) {
        if (succ)
            return step;
    
        int h = getremainder();
        if (h == 0) {
            succ = true;
            return step;
        }
        if (step + h > bound)
            return step + h;
    
        int newbound = 1e9;
        for (int i = 0; i < 8; i++) {
            change(i);
            Q[qc++] = i;
            int f = dfs(step + 1);
            if (succ)
                return f;
            newbound = min(f, newbound);
    
            qc -= 1;
            change(rev[i]);
        }
        return newbound;
    }
    
    int main() {
        while (scanf("%d", &square[0]) && square[0]) {
            for (int i = 1; i < 24; i++)
                scanf("%d", &square[i]);
    
            if (!getremainder()) {
                printf("No moves needed\n%d\n", square[aim[0]]);
                continue;
            }
            qc = bound = 0;
            succ = false;
            while (!succ) {
                bound = dfs(0);
            }
            for (int i = 0; i < qc; i++)
                printf("%c", Q[i] + 'A');
            printf("\n%d\n", square[aim[0]]);
        }
        return 0;
    }
  • 相关阅读:
    Codeforces 877 C. Slava and tanks
    Codeforces 877 D. Olya and Energy Drinks
    2017 10.25 NOIP模拟赛
    2017 国庆湖南 Day1
    UVA 12113 Overlapping Squares
    学大伟业 国庆Day2
    51nod 1629 B君的圆锥
    51nod 1381 硬币游戏
    [JSOI2010]满汉全席
    学大伟业 2017 国庆 Day1
  • 原文地址:https://www.cnblogs.com/kedebug/p/2989823.html
Copyright © 2011-2022 走看看