您的位置:首页 > 其它

hihoCoder 1233 Boxes 哈希+最短路

2015-10-09 16:36 399 查看
题意:给你n(n<8)个盒子,每个盒子上有一个方块,每个方块都有其独特的重量。现有一种合法操作,每次操作选择一个盒子上的最上面的方块,可左右移动,并且使得移动后方块位于盒子最上方,且其重量是盒子上所有方块中质量最小的。问:如果通过最少次合法操作,使得方块上的盒子质量有序。

方法:注意到n很少,可采取哈希的方法,来确定此状态到终状态的最少步数。

哈希方法:可以用n进制的数来表示每个方块位于第几个盒子。

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <queue>
using namespace std;
const int N=1e6;
int dp[8]
;
int a[8],b[8],pos[8];
int Hash(int n){
int ret=0;
for(int i=0;i<n;i++)ret=ret*n+pos[i];
return ret;
}
queue<int>q;
int last[8];
void init(int n){
for(int i=0;i<n;i++)pos[i]=n-1;
int Max=Hash(n);
for(int i=0;i<=Max;i++)dp
[i]=-1;
for(int i=0;i<n;i++)pos[i]=i;
int cur=Hash(n);
dp
[cur]=0;
q.push(cur);
while(!q.empty()){
cur=q.front();q.pop();
int ccur=cur;
for(int i=n-1;i>=0;i--)pos[i]=cur%n,cur/=n,last[i]=-1;
for(int i=n-1;i>=0;i--)last[pos[i]]=i;
for(int i=0;i<n;i++){
if(last[i]==-1)continue;
//left
int x=last[i];
if(i-1>=0){
if(last[i-1]==-1||last[i-1]>last[i]){
pos[x]--;
int temp=Hash(n);
if(dp
[temp]==-1||dp
[temp]>dp
[ccur]+1){
dp
[temp]=dp
[ccur]+1;
q.push(temp);
}
pos[x]++;
}
}
if(i+1<n){
if(last[i+1]==-1||last[i+1]>last[i]){
pos[x]++;
int temp=Hash(n);
if(dp
[temp]==-1||dp
[temp]>dp
[ccur]+1){
dp
[temp]=dp
[ccur]+1;
q.push(temp);
}
pos[x]--;
}
}
}
}
}
void work(){
for(int i=1;i<8;i++)
init(i);
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%d",&a[i]),b[i]=a[i];
sort(b,b+n);
for(int i=0;i<n;i++)a[i]=lower_bound(b,b+n,a[i])-b;
for(int i=0;i<n;i++)pos[a[i]]=i;
printf("%d\n",dp
[Hash(n)]);
}
}
int main(){
freopen("data.in","r",stdin);
work();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: