24h購物| | PChome| 登入
2012-11-27 08:31:32| 人氣1,047| 回應0 | 上一篇 | 下一篇

[UVA][IDA*][Faster] 10181 - 15-Puzzle Problem

推薦 0 收藏 0 轉貼0 訂閱站台

Problem N

15-Puzzle Problem

Input: standard input

Output: standard output

Time Limit: 45 seconds

 

The 15-puzzle is a very popular game; even if you don't know it by that name, you've seen it.  It is constructed with 15 sliding tiles, each with a number from 1 to 15 on it, and all packed into a 4 by 4 frame with one tile missing. The object of the puzzle is to arrange the tiles so that they are ordered as below:

Here the only legal operation is to exchange missing tile with one of the tiles with which it shares an edge.  As an example, the following sequence of moves changes the status of a puzzle

A random puzzle position

The missing Tile moves to right. Denoted by R

The missing Tile moves upwards. Denoted by U

The missing Tile moves to the left. Denoted by L

The letters in the previous row indicate which neighbor of the missing tile is swapped with it at each step; legal values are 'R','L','U' and 'D', for RIGHT, LEFT, UP, and DOWN, respectively.

Given an initial configuration of a 15-puzzle you will have to determine the steps that would make you reach the final stage. The input 15-puzzles requires at most 45 steps to be solved with our judge solution. So you will not be allowed to use more than 50 steps to solve a puzzle. If the given initial configuration is not solvable you just need to print the line “This puzzle is not solvable.”

 

Input

The first line of the input contains one integer N, which indicates how many sets of puzzle, will be given as input. Next 4N lines contain N sets of inputs. It means four lines make one set of input. Zero denotes the missing tile.

 

Output

For each set of input you will have to give one line of output. If the input puzzle is not solvable then print the line “This puzzle is not solvable.” If the puzzle is solvable then print the move sequence as described above to solve the puzzle.

 

Sample Input:

2
2 3 4 0
1 5 7 8
9 6 10 12
13 14 11 15
13 1 2 4
5 0 3 7
9 6 10 12
15 8 11 14

 

Sample Output:

LLLDRDRDR
This puzzle is not solvable.


優化了一些地方,加上常數的估價倍率改變 0.008 s 神速

#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#define LLU unsigned long long
using namespace std;
struct status {
    char board[4][4];
    int ix, iy;
} init;
int pos[16][2], mxdep;
int dir[4][2] = {{0,-1},{-1,0},{1,0},{0,1}};/*u,l,r,d*/
char dirc[4] = {'L', 'U', 'D', 'R'}, path[100];
int solved;
bool solvable() {
    int sum = 0, row, i, j;
    for(i = 0; i < 16; i++) {
        if(init.board[i/4][i%4] == 0) {
            row = i/4 + 1;
            continue;
        }
        for(j = i+1; j < 16; j++) {
            if(init.board[j/4][j%4] < init.board[i/4][i%4]) {
                if(init.board[j/4][j%4])
                    sum++;
            }
        }
    }
    return 1-(sum+row)%2;
}
int H() {
    static int i, j, sum, num;
    sum = 0;
    for(i = 0; i < 4; i++) {
        for(j = 0; j < 4; j++) {
            num = init.board[i][j];
            if(num == 0)
                continue;
            sum += abs(i-pos[num][0]) + abs(j-pos[num][1]);
        }
    }
    return sum;
}
int Htable[4][4][16];
int IDA(int dep, int hv, int prestep) {
    if(hv == 0) {
        solved = dep;
        path[dep] = '\0';
        puts(path);
        return dep;
    }
    if(dep + 5*hv/3 > mxdep) {
        return dep + 5*hv/3;
    }
    int i, tx, ty, x = init.ix, y = init.iy;
    int submxdep = 0xfff, val = 0xfff, shv;

    for(i = 0; i < 4; i++) {
        if(i + prestep == 3)    continue;
        tx = x + dir[i][0], ty = y + dir[i][1];
        if(tx < 0 || ty < 0 || tx > 3 || ty > 3)
            continue;

        shv = hv;
        shv -= Htable[tx][ty][init.board[tx][ty]];
        shv += Htable[x][y][init.board[tx][ty]];
        init.ix = tx, init.iy = ty;
        swap(init.board[x][y], init.board[tx][ty]);

        path[dep] = dirc[i];
        val = IDA(dep+1, shv, i);

        swap(init.board[x][y], init.board[tx][ty]);
        init.ix = x, init.iy = y;
        if(solved)  return solved;
        submxdep = min(submxdep, val);
    }
    return submxdep;
}
int main() {
    int test, i, j, k, initH;
    int cases = 0;
    for(i = 0, k = 0; i < 4; i++)
        for(j = 0; j < 4; j++)
            pos[++k][0] = i, pos[k][1] = j;
    for(i = 0; i < 4; i++)
        for(j = 0; j < 4; j++)
            for(k = 1; k < 16; k++)
                Htable[i][j][k] = abs(i - pos[k][0]) + abs(j - pos[k][1]);
    scanf("%d", &test);
    while(test--) {
        cases++;
        for(i = 0; i < 4; i++) {
            for(j = 0; j < 4; j++) {
                scanf("%d", &k);
                init.board[i][j] = k;
                if(init.board[i][j] == 0) {
                    init.ix = i, init.iy = j;
                }
            }
        }
        if(solvable()) {
            solved = 0, initH = mxdep = H();
            if(!mxdep) {
                puts("");
                continue;
            }
            while(solved == 0)
                mxdep = IDA(0, initH, -1);
            //printf("%d\n", solved);
        }else {
            puts("This puzzle is not solvable.");
        }
    }
    return 0;
}
/*
2
6 2 8 4
12 14 1 10
13 15 3 9
11 0 5 7
0 1 3 8
5 7 4 6
9 2 10 11
13 14 15 12
*/

台長: Morris
人氣(1,047) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 不分類 | 個人分類: UVA |
此分類下一篇:[UVA][烏龜塔][Greedy解] 10154 - Weights and Measures
此分類上一篇:[UVA][IDA*] 10181 - 15-Puzzle Problem

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文