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\n", k);
    }
    return 0;
}
View Code

 

posted @ 2015-03-05 21:01  NanoApe  阅读(177)  评论(0编辑  收藏  举报
AmazingCounters.com