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
  • 相关阅读:
    UVa532 Dungeon Master 三维迷宫
    6.4.2 走迷宫
    UVA 439 Knight Moves
    UVa784 Maze Exploration
    UVa657 The die is cast
    UVa572 Oil Deposits DFS求连通块
    UVa10562 Undraw the Trees
    UVa839 Not so Mobile
    327
    UVa699 The Falling Leaves
  • 原文地址:https://www.cnblogs.com/NanoApe/p/4316710.html
Copyright © 2011-2022 走看看