zoukankan      html  css  js  c++  java
  • HDU-2234 无题I

    为每个状态定义两个函数S和H,分别表示当前状态到列一致和行一致的目标状态的最少操作次数。

    然后有了估价函数F=Min(S,H)就可以IDA*了。

    #include <cstdio>
    #include <iostream>
    #include <fstream>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    
    #define rep(i, l, r) for(int i=l; i<=r; i++)
    #define down(i, l, r) for(int i=l; i>=r; i--)
    #define maxn 40320
    #define MAX 1<<30
    
    using namespace std;
    
    int t, n[5][5], k;
    
    inline void Up(int x) { int a; a = n[1][x]; n[1][x] = n[2][x]; n[2][x] = n[3][x]; n[3][x] = n[4][x]; n[4][x] = a; }
    inline void Down(int x) { int a; a = n[4][x]; n[4][x] = n[3][x]; n[3][x] = n[2][x]; n[2][x] = n[1][x]; n[1][x] = a; }
    inline void Right(int x) { int a; a = n[x][4]; n[x][4] = n[x][3]; n[x][3] = n[x][2]; n[x][2] = n[x][1]; n[x][1] = a; }
    inline void Left(int x) { int a; a = n[x][1]; n[x][1] = n[x][2]; n[x][2] = n[x][3]; n[x][3] = n[x][4]; n[x][4] = a; }
    
    int S()
    {
        int b[5], o, o2 = 0;
        rep(i, 1, 4) 
        {
            rep(j, 1, 4) b[j] = 0; o = 0;
            rep(j, 1, 4) b[n[j][i]]++;
            rep(j, 1, 4) o = max(o, b[j]);
            o2 = max(o2, 4-o);
        }
        return o2;
    }
    
    int H()
    {
        int b[5], o, o2 = 0;
        rep(i, 1, 4) 
        {
            rep(j, 1, 4) b[j] = 0; o = 0;
            rep(j, 1, 4) b[n[i][j]]++;
            rep(j, 1, 4) o = max(o, b[j]);
            o2 = max(o2, 4-o);
        }
        return o2;
    }
    
    bool Search(int x)
    {
        if (x == k)
        {
            if (!S() || !H()) return true; else return false;
        }
        int now = min(S(), H()); if (now > k-x) return false;
        Left(1); if (min(S(), H()) <= now) if (Search(x+1)) return true; Right(1);
        Left(2); if (min(S(), H()) <= now) if (Search(x+1)) return true; Right(2);
        Left(3); if (min(S(), H()) <= now) if (Search(x+1)) return true; Right(3);
        Left(4); if (min(S(), H()) <= now) if (Search(x+1)) return true; Right(4);
        Right(1); if (min(S(), H()) <= now) if (Search(x+1)) return true; Left(1);
        Right(2); if (min(S(), H()) <= now) if (Search(x+1)) return true; Left(2);
        Right(3); if (min(S(), H()) <= now) if (Search(x+1)) return true; Left(3);
        Right(4); if (min(S(), H()) <= now) if (Search(x+1)) return true; Left(4);
        Up(1); if (min(S(), H()) <= now) if (Search(x+1)) return true; Down(1);
        Up(2); if (min(S(), H()) <= now) if (Search(x+1)) return true; Down(2);
        Up(3); if (min(S(), H()) <= now) if (Search(x+1)) return true; Down(3);
        Up(4); if (min(S(), H()) <= now) if (Search(x+1)) return true; Down(4);
        Down(1); if (min(S(), H()) <= now) if (Search(x+1)) return true; Up(1);
        Down(2); if (min(S(), H()) <= now) if (Search(x+1)) return true; Up(2);
        Down(3); if (min(S(), H()) <= now) if (Search(x+1)) return true; Up(3);
        Down(4); if (min(S(), H()) <= now) if (Search(x+1)) return true; Up(4);
        return false;
    }
    
    int main()
    { 
        scanf("%d", &t);
        while (t--)
        {
            rep(i, 1, 4) rep(j, 1, 4) scanf("%d", &n[i][j]);
            k = 0;
            while (k <= 5)
                if (Search(0)) break; else k++;
            if (k == 6) k = -1; printf("%d
    ", k);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    MFC STATIC,Picture控件使用及无法添加变量的问题
    MFC listctrl NMCLICK消息 错误 无法从"NMHDR*"转换为"NMITEMACTIVATE"
    vs2008中将开始执行按钮(不调试按钮)添加至标准工具栏方法
    MFC 删除工具栏 默认对话框全屏 修改MFC标题栏的文字 删除菜单栏
    Visual Assist X设置
    MFC禁止窗口最大化按钮和禁止改变窗口大小
    MFC从头开始如何利用MFC分割窗口
    MFC CSplitterWnd窗口分割
    关于VS2008下提示microsoft incremental linker已停止工作的问题
    windows 下codeblocks查看容器值
  • 原文地址:https://www.cnblogs.com/NanoApe/p/4316710.html
Copyright © 2011-2022 走看看