您的位置:首页 > 其它

[置顶] HihoCoder 1233 Boxes(bfs打表)

2016-10-27 23:35 309 查看
题意:给出一列箱子,小箱子只能往大箱子上面放,问最少需要多少步使箱子严格升序排列

题解:

离散化大小之后得到7种箱子,那么状态总数最多77种,直接预处理所有情况打表,由于每一个箱子都有唯一的坐标,直接以此为关键值得到一个十进制整数作为当前状态存储访问标记和答案。

#include<cstring>
#include<string>
#include<iostream>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<map>
#include<cstdlib>
#include<cmath>
#include<vector>
//#pragma comment(linker, "/STACK:1024000000,1024000000");

using namespace std;

#define INF 0x3f3f3f3f

struct node
{
int x[9];//数字下标
int y[9];//下标数字
int val;
int step;
};

bool judge(node temp,int n)
{
int vis[10];
memset(vis,0,sizeof vis);
for(int i=1; i<=n; i++)
{
if(vis[ temp.x[i] ]) return false;
vis[temp.x[i]]=1;
}
return true;
}

void trans(node &t,int i,int j,int n)
{
int num=t.y[i];
t.x[num]=j;
t.y[j]=num;
t.y[i]=INF;
for(int p=1; p<=n; p++)
{
if(t.x[p]==i)
{
t.y[i]=p;
break;
}
}
int sum=0;
for(int p=1; p<=n; p++)
{
sum=sum*10+t.x[p];
}
t.val=sum;
}

queue<node>que;
int ans[8888888];
bool mp[8888888];

void bfs(node temp,int n)
{
temp.y[0]=temp.y[n+1]=-1;
while(que.size()) que.pop();
que.push(temp);
while(que.size())
{
temp=que.front();
que.pop();
if(mp[temp.val]) continue;
mp[temp.val]=true;
if(judge(temp,n))
{
if(!ans[temp.val]) ans[temp.val]=temp.step;
else ans[temp.val]=min(ans[temp.val],temp.step);
}
for(int i=1; i<=n; i++)
{
node t=temp;
t.step++;
if(t.y[i]<t.y[i+1])
{
trans(t,i,i+1,n);
que.push(t);
}
t=temp;
t.step++;
if(t.y[i]<t.y[i-1])
{
trans(t,i,i-1,n);
que.push(t);
}
}
}
}

void init()
{
for(int i=2; i<=7; i++)
{
node temp;
temp.step=1;
temp.val=0;
for(int j=1; j<=i; j++)
{
temp.x[j]=j;
temp.y[j]=j;
temp.val=temp.val*10+j;
}
bfs(temp,i);
}
}

int a[20];
int main()
{
init();
int T;
scanf("%d",&T);
while(T--)
{
int n;
vector<int>vec;
scanf("%d",&n);
for(int i=0; i<n; i++)
{
scanf("%d",&a[i]);
vec.push_back(a[i]);
}
if(n==1||n==0)
{
printf("0\n");
continue;
}
sort(vec.begin(),vec.end());
vec.erase(unique(vec.begin(),vec.end()),vec.end());
int sum=0;
int vis[10];
for(int i=0; i<n; i++)
{
a[i]=lower_bound(vec.begin(),vec.end(),a[i])-vec.begin()+1;
vis[a[i]]=i+1;
}
for(int i=1;i<=n;i++) sum=sum*10+vis[i];
printf("%d\n",ans[sum]-1);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: