• POJ2286:The Rotation Game


    Description

    POJ传送门

    (简化版)只输出操作次数,不用输出方案。

    Solution

    直接爆搜?显然复杂度会炸。

    考虑优化,我们想到 (IDA*)(迭代加深搜索),这篇博客默认你已经会了这个算法,如果还不会的话可以去网上搜一下。

    不难发现,本题的乐观估价函数为 (8 - cnt)(中间 8 个数中出现次数最多的数的个数)

    如果这个值加上我们已经走了的步数大于当前预期的步数,那么直接 (return)

    反之继续搜索。

    Code

    我把这个 字,存到了 8 * 8 的数组中。

    (update) (即操作)时,循环赋值。

    (非常丑陋)

    #include <iostream>
    #include <cstdio>
    #define ri register int
    
    using namespace std;
    
    const int N = 10;
    int a[N][N];
    int cnt;
    int arc[8] = {5, 4, 7, 6, 1, 0, 3, 2};//回溯用的,为了反着操作一遍
    
    inline int check(){//乐观估价函数
        int t[5] = {0};
        for(ri i = 3; i <= 5; i++)
            for(ri j = 3; j <= 5; j++)
                t[a[i][j]]++;
        ri maxs = 0;
        maxs = max(max(t[1], t[2]), t[3]);
        return 8 - maxs;
    }
    
    inline void solve_row(int row, int k){//列上操作
        if(k < 0){
            ri res = a[1][row];
            for(ri i = 1; i < 7; i++)
                a[i][row] = a[i + 1][row];
            a[7][row] = res;
        }else{
            ri res = a[7][row];
            for(ri i = 7; i > 1; i--)
                a[i][row] = a[i - 1][row];
            a[1][row] = res;
        }
    }
    
    inline void solve_line(int line, int k){//行上操作
        if(k < 0){
            ri res = a[line][1];
            for(ri i = 1; i < 7; i++)
                a[line][i] = a[line][i + 1];
            a[line][7] = res;
        }else{
            ri res = a[line][7];
            for(ri i = 7; i > 1; i--)
                a[line][i] = a[line][i - 1];
            a[line][1] = res;
        }
    }
    
    inline void update(int k){//8 个位置
        if(k == 0) solve_row(3, -1);
        else if(k == 1) solve_row(5, -1);
        else if(k == 2) solve_line(3, 1);
        else if(k == 3) solve_line(5, 1);
        else if(k == 4) solve_row(5, 1);
        else if(k == 5) solve_row(3, 1);
        else if(k == 6) solve_line(5, -1);
        else if(k == 7) solve_line(3, -1);
    }
    
    inline int dfs(int step){
        if(step == cnt){
            if(!check()) return 1;
            return 0;
        }
        if(check() + step > cnt) return 0;
        for(ri i = 0; i < 8; i++){
            update(i);
            if(dfs(step + 1)) return 1;
            update(arc[i]);//要update回来
        }
        return 0;
    }
    
    int main(){
        while(scanf("%d", &a[1][3]) && a[1][3]){
            scanf("%d%d%d", &a[1][5], &a[2][3], &a[2][5]);
            for(int i = 1; i <= 7; i++)
                scanf("%d", &a[3][i]);
            scanf("%d%d", &a[4][3], &a[4][5]);
            for(int i = 1; i <= 7; i++)
                scanf("%d", &a[5][i]);
            scanf("%d%d%d%d", &a[6][3], &a[6][5], &a[7][3], &a[7][5]);//极其丑陋的初始化
            for(cnt = 0; ; cnt++){
                if(dfs(0))
                    break;
            }
            printf("%d
    ", cnt);
        }
        return 0;
    }
    

    End

    本文来自博客园,作者:xixike,转载请注明原文链接:https://www.cnblogs.com/xixike/p/15327677.html

  • 相关阅读:
    学习笔记 四边形不等式的模型
    题解 AT2230【Water Distribution】
    题解 CF848C 【Goodbye Souvenir】
    第二届全国大学生算法设计与编程挑战赛(春季赛)正式赛题解&比赛回顾
    积性函数相关学习笔记
    【MySQL】数据库备份
    【SpringMVC】SSM的maven依赖
    【SpringMVC】Jackson解决乱码问题配置
    【SpringMVC】DispatcherServlet与中文过滤器配置
    【Spring】学习笔记008--AOP实现方式
  • 原文地址:https://www.cnblogs.com/xixike/p/15327677.html
Copyright © 2020-2023  润新知