sicily 1150. 简单魔板 & 1151. 魔板

来源:互联网 发布:淘宝积分抽奖在哪里 编辑:程序博客网 时间:2024/04/28 18:51

典型的广搜题目:

1)       首先把初始状态所代表的节点压入队列,初始节点的状态为12348765,父节点位置为-1(表示没有父节点),op为空,表示没有操作,标记初始节点的状态已访问,初始化step(表示当前搜索的层次)为0;

2)       当队列不为空(head< tail),一直循环以下步骤;

3)       用一个curTail记录当前队列的队尾,这表示了从head到curTail为层次为step的这一层,对这一层的节点进行扩展。

4)       对于当前这一层的所有节点,首先判断它的状态是否为目标状态,如果是表示找到了结果,标记成功并且输出路径,退出。如果不是目标状态,则分别按照A、B、C三个操作来扩展,如果扩展之后的节点状态是以前没有达到过的,那么就压入队列(tail++),并且标记该状态已访问(对于每一个状态可以通过康托展开来做hash,使得一个节点映射为一个更小的整数)。

5)       当前整一层访问完毕,step++,如果step大于了输入的N,则退出,表示没有完成任务。

6)       如果step不大于输入的N,表示搜索没有结束,转到第2)步继续进行。

#include <cstdio>#include <cstring>int fact[] = {1, 1, 2, 6, 24, 120, 720, 5040};bool vis[40500];struct Node{int state, p;char op;}que[40500];int op(int state, int c)//三步操作{int res = 0;switch(c){case 1:res = state/10000 + state%10000*10000;break;case 2:res = state/10000%10*10000000 + state/100000*10000+state%10*1000 + state/10%1000;break;case 3:res = state/10000000*10000000 + state/100%10*1000000 + state/1000000%10*100000 + state/10000%10*10000+ state/1000%10*1000 + state/10%10*100+ state/100000%10*10 + state%10;break;}return res;}int hash(int state)//康托展开{char str[10];int res = 0;sprintf(str, "%d", state);for(int i=0; i<8; i++){int cnt = 0;for(int j=i+1; j<8; j++)if(str[i] > str[j])cnt++;res += cnt*fact[7-i];}return res;}void print(int p)//打印路径{if(p != -1){print(que[p].p);printf("%c", que[p].op);}}int main(){int M, startState = 12348765;while(scanf("%d", &M), M != -1){int endState = 0, val, step = 0, head = 0, tail = 1;bool hasfinished = false;for(int i=0; i<8; i++){scanf("%d", &val);endState = endState*10 + val;}memset(vis, false, sizeof(vis));que[0].state = startState, que[0].p = -1;vis[hash(startState)] = true;while(head < tail && !hasfinished)//队列不为空,或者搜索还未结束,继续{int curTail = tail;//curTail为测试为step的这一层的最后一个节点的位置while(head < curTail){int curState = que[head++].state;if(curState == endState){printf("%d ", step);print(head-1);printf("\n");hasfinished = true;break;}for(int i=1; i<=3; i++){int tmp = op(curState, i);int tmpHash = hash(tmp);if(!vis[tmpHash]){vis[tmpHash] = true;que[tail].state = tmp, que[tail].p = head - 1, que[tail++].op = (char)(i- 1+'A');}}}step++;//搜索层次加一if(step > M)break;}if(!hasfinished)printf("-1\n");}return 0;}


原创粉丝点击