hiho1233--Boxes(BFS)

来源:互联网 发布:微信专用淘宝二维码 编辑:程序博客网 时间:2024/06/11 23:17

题目大意:有n个盘子,n个柱子,每个柱子上都有一个盘子,任意两个盘子大小均不相同,一个盘子可以移动到相邻的柱子上,且必须比该柱子最上方的盘子要小,问最少移动多少次后,盘子从小到大依次摆在每个柱子上。


分析:首先,最少步的问题,说明,要用BFS。

          其次,多个起点,固定终点,说明,可以预处理,反向BFS。

          然后,就是考虑如何表示状态了。由于一个柱子上可以有多个盘子,所以,并不能有盘子的编号来表示状态。于是,我们可以考虑用每个盘子的位置表示当前的状态。又n最大为7,所以状态数最多8^7种。


代码:

#include <cstdio>#include <iostream>#include <cstring>#include <queue>#include <algorithm>using namespace std;#define maxn 11111111int dp[maxn];   //从初始状态到每种状态的最小步数int pos[10];    //pos[i] = j,表示第j个盘子在第i个位置int dig[10];    //dig[i] = j,表示第i个盘子移动一次,状态变化jvoid bfs(int x) {    int state, t, temp, head;    dig[x] = 1;    for(int i = x-1; i >= 1; i--)        dig[i] = dig[i+1]*8;    state = 0;    for(int i = 1; i <= x; i++)        state = state*8+i;    dp[state] = 0;    queue<int> q;    q.push(state);    while(!q.empty()) {        t = head = q.front();        q.pop();        memset(pos, 0, sizeof(pos));        for(int i = x; i >= 1; i--, t /= 8)     //确定每个位置最上方的盘子            pos[t%8] = i;        for(int i = 1; i <= x; i++) {            if(pos[i] == 0) continue;            if(i > 1 && (pos[i] < pos[i-1] || !pos[i-1])) {     //第i个盘子向前移                temp = head-dig[pos[i]];                if(dp[temp] == -1) {                    dp[temp] = dp[head]+1;                    q.push(temp);                }            }            if(i < x && (pos[i] < pos[i+1] || !pos[i+1])) {    //第i个盘子向后移                temp = head+dig[pos[i]];                if(dp[temp] == -1) {                    dp[temp] = dp[head]+1;                    q.push(temp);                }            }        }    }}void init() {    memset(dp, -1, sizeof(dp));    for(int i = 1; i <= 7; i++)        bfs(i);}int main() {    init();    int n, T, loc[11111], a[10];    //loc[i]表示盘子i所在的位置    scanf("%d", &T);    while(T--) {        scanf("%d", &n);        for(int i = 1; i <= n; i++) {            scanf("%d", &a[i]);            loc[a[i]] = i;        }        sort(a+1, a+n+1);        int st = 0;        for(int i = 1; i <= n; i++)            st = st*8 +loc[a[i]];        printf("%d\n", dp[st]);    }    return 0;}


0 0