題目連結
TLE 幾百次後 才發現原因在 board[0][k] 居然不等於 board[k/4][k%4],
改一下就AC了...害我一直對ida*優化到0秒
/* 題目: UVa 10181 - 15-Puzzle Problem
* Language: C++
* Created on: 2016年10月02日
* Author: hanting
*/
#include <iostream>
#include <cmath>
#include <vector>
#include <cstdio>
#include <cstring>
using namespace std;
int board[4][4];
int table[16][2];
inline bool canSolve(int x)
{
int result = 0;
for(int i = 0; i < 16; i++)
{
for(int j = i+1; j < 16; j++)
{
if(board[j/4][j%4] and board[i/4][i%4] and board[j/4][j%4] < board[i/4][i%4]) result++;
}
}
return (result+x)&1;
}
inline int getStatus()
{
int cnt = 0;
for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 4; j++)
{
if(board[i][j]) cnt += abs(table[board[i][j]][0] - i) + abs(table[board[i][j]][1] - j);
}
}
return cnt;
}
char ansStk[100];
char stk[100];
int stki;
enum
{
UP, DOWN, LEFT, RIGHT
};
int maxd;
int tmpMaxd;
int Htable[4][4][16]; // Htable[i][j][num] // num在[i][j]的cost
bool no;
bool dfs(int depth, int i, int j, int prePos, int status)
{
if(depth > 50)
{
no = true;
return false;
}
if(depth + status*4/3 > maxd)
{
tmpMaxd = min(tmpMaxd, depth + status*4/3);
if(depth == 0) maxd = tmpMaxd;
return false;
}
if(status == 0)
{
stk[stki] = 0;
cout << stk;
return true;
}
if(prePos != UP and i+1 < 4)
{
swap(board[i][j], board[i+1][j]);
stk[stki++] = 'D';
int nextStatus = status;
nextStatus -= Htable[i+1][j][board[i][j]];
nextStatus += Htable[i][j][board[i][j]];
if(dfs(depth+1 , i+1, j, DOWN, nextStatus) ) return true;
stki--;
swap(board[i][j], board[i+1][j]);
}
if(prePos != LEFT and j+1 < 4)
{
swap(board[i][j], board[i][j+1]);
stk[stki++] = 'R';
int nextStatus = status;
nextStatus -= Htable[i][j+1][board[i][j]];
nextStatus += Htable[i][j][board[i][j]];
if(dfs(depth+1 , i, j+1, RIGHT, nextStatus) ) return true;
stki--;
swap(board[i][j], board[i][j+1]);
}
if(prePos != DOWN and i-1 >= 0)
{
swap(board[i][j], board[i-1][j]);
stk[stki++] = 'U';
int nextStatus = status;
nextStatus -= Htable[i-1][j][board[i][j]];
nextStatus += Htable[i][j][board[i][j]];
if(dfs(depth+1, i-1, j, UP, nextStatus) ) return true;
stki--;
swap(board[i][j], board[i-1][j]);
}
if(prePos != RIGHT and j-1 >= 0)
{
swap(board[i][j], board[i][j-1]);
stk[stki++] = 'L';
int nextStatus = status;
nextStatus -= Htable[i][j-1][board[i][j]];
nextStatus += Htable[i][j][board[i][j]];
if(dfs(depth+1 , i, j-1, LEFT, nextStatus) ) return true;
stki--;
swap(board[i][j], board[i][j-1]);
}
maxd = tmpMaxd;
return false;
}
int main()
{
for(int i = 1; i < 16; i++)
{
table[i][0] = (i-1) / 4;
table[i][1] = (i-1) % 4 ;
}
for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 4; j++)
{
for(int k = 1; k < 16; k++)
{
Htable[i][j][k] = abs(table[k][0] - i) + abs(table[k][1] -j);
}
}
}
int n;
cin >> n;
while(n--)
{
int x0, y0;
memset(ansStk, 0, sizeof(ansStk));
int ti = 0;
for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 4; j++)
{
cin >> board[i][j];
if(board[i][j] == 0)
{
x0 = i;
y0 = j;
}
}
}
if(!canSolve(x0))
{
cout << "This puzzle is not solvable." << endl;
continue;
}
int status = getStatus();
maxd = status;
no = false;
for(;;)
{
tmpMaxd = 0x3fffffff;
stki = 0;;
if(dfs(0, x0, y0, -1, status))
{
break;
}
if(no)
{
cout << "This puzzle is not solvable." ;
break;
}
}
cout << endl;
}
return 0;
}
2016年10月2日 星期日
[UVA] 10181 - 15-Puzzle Problem
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言