2015年北京网赛 boxes(bfs)
题目链接:
http://hihocoder.com/problemset/problem/1233
题目描述:
给定最多七个箱子,每个箱子的重量都不相同,每次都可以将一个箱子放在相邻的位置上,如果相邻位置上的箱子的重量比它大,那么可以放在相邻位置上的箱子,
小就不可以,问通过这样的操作最少需要多少步可以将这些箱子排好序?
由于最多是7个箱子,而且每个箱子的重量都不相同,那么最多有7!个状态,通过bfs每次需要更新的状态最多有12个状态,可以承受。
接下来就是怎样表示状态了,由于某一个位置可能会有很多个数,所以不能直接记录,可以记录每个数所在的位置来表示状态。
还有一点就是需要将大数化小数,同样是记录位置,然后排个序,找出它们之间的大小关系,就可以大数化小数了。
#include <stdio.h> #include <cstdlib> #include <cstring> #include <queue> #include <algorithm> using namespace std; int vis2[8][8]; int vis3[8][8][8]; int vis4[8][8][8][8]; int vis5[8][8][8][8][8]; int vis6[8][8][8][8][8][8]; int vis7[8][8][8][8][8][8][8]; bool check(int a[],int n,int step){ if(n==2){ if(vis2[a[1]][a[2]]!=-1) return 0; else { vis2[a[1]][a[2]]=step;return 1; } } else if(n==3){ if(vis3[a[1]][a[2]][a[3]]!=-1) return 0; else { vis3[a[1]][a[2]][a[3]]=step;return 1; } } else if(n==4){ if(vis4[a[1]][a[2]][a[3]][a[4]]!=-1) return 0; else { vis4[a[1]][a[2]][a[3]][a[4]]=step;return 1; } } else if(n==5){ if(vis5[a[1]][a[2]][a[3]][a[4]][a[5]]!=-1) return 0; else { vis5[a[1]][a[2]][a[3]][a[4]][a[5]]=step;return 1; } } else if(n==6){ if(vis6[a[1]][a[2]][a[3]][a[4]][a[5]][a[6]]!=-1) return 0; else { vis6[a[1]][a[2]][a[3]][a[4]][a[5]][a[6]]=step;return 1; } } else if(n==7){ if(vis7[a[1]][a[2]][a[3]][a[4]][a[5]][a[6]][a[7]]!=-1) return 0; else { vis7[a[1]][a[2]][a[3]][a[4]][a[5]][a[6]][a[7]]=step;return 1; } } } struct node { int pos[10]; int step; }; void bfs(int n) { int a[10]; node start; for(int i=1;i<=n;i++) a[i]=i; check(a,n,0); //首先初始化,起始状态step等于0 for(int i=1;i<=n;i++) start.pos[i]=i; start.step=0; queue < node > que; que.push(start); while(!que.empty()) { node cur=que.front(); que.pop(); for(int i=1;i<=n;i++) { int l=0,r=0; for(int j=1;j<i;j++) { if(cur.pos[j]==cur.pos[i]-1) l=1; //l==1,说明左边比它小,不能往左移 if(cur.pos[j]==cur.pos[i]+1) r=1; if(cur.pos[j]==cur.pos[i]) l=r=1;//不能左移或者右移 } if(cur.pos[i]-1<1) l=1; if(cur.pos[i]+1>n) r=1; if(l==0) { cur.pos[i]--; cur.step++; if(check(cur.pos,n,cur.step)) que.push(cur); cur.pos[i]++; cur.step--; } if(r==0) { cur.pos[i]++; cur.step++; if(check(cur.pos,n,cur.step)) que.push(cur); cur.pos[i]--; cur.step--; } } } } void init() { memset(vis2,-1,sizeof(vis2)); memset(vis3,-1,sizeof(vis3)); memset(vis4,-1,sizeof(vis4)); memset(vis5,-1,sizeof(vis5)); memset(vis6,-1,sizeof(vis6)); memset(vis7,-1,sizeof(vis7)); for(int i=2;i<=7;i++) bfs(i); } struct num { int data,id; }input[10]; bool cmp(num a,num b) { if(a.data<b.data) return 1; else return 0; } int main() { int b[10]; // freopen("test.txt","r",stdin); int t; scanf("%d",&t); init(); while(t--) { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&input[i].data); input[i].id=i; } sort(input+1,input+n+1,cmp); for(int i=1;i<=n;i++) { b[i]=input[i].id; } if(n==1) printf("0\n"); if(n==2) printf("%d\n",vis2[b[1]][b[2]]); if(n==3) printf("%d\n",vis3[b[1]][b[2]][b[3]]); if(n==4) printf("%d\n",vis4[b[1]][b[2]][b[3]][b[4]]); if(n==5) printf("%d\n",vis5[b[1]][b[2]][b[3]][b[4]][b[5]]); if(n==6) printf("%d\n",vis6[b[1]][b[2]][b[3]][b[4]][b[5]][b[6]]); if(n==7) printf("%d\n",vis7[b[1]][b[2]][b[3]][b[4]][b[5]][b[6]][b[7]]); } return 0; }