描述:采用双广搜完成,因为单广搜层数太多,不但超时(结果根本出不来),而且还超内存(开不下这么大的数组),双广搜分为两部分,每部分的层数都为8层,分别是从开始的转轮和最终的转轮开始广搜,遇到重合了就可以输出路径,如果不重合,顶多两部分全都搜完,由于目标转轮是确定的,所以第一次的从目标转轮进行的广搜可以存储下来,以后只需要从开始的转轮广搜就可以了,这样可以节省时间。 #include <stdio.h> #include <string.h> #define MAX 200000 #define HASHSIZE 10000003 struct way { int step; int l; int len; int s[21]; }; int head[2][HASHSIZE], next[2][MAX]; int a[24]; int front, rear,mid, flag; int target[21] = {0, 3, 4, 3, 0, 5, 6, 5, 0, 1, 2, 1, 0, 7, 8, 7, 0, 9, 10, 9, 0}; way v[MAX]; int hash(int *p) { int c = 0; for (int i = 0; i < 21; i++) c = (c * 10 + p[i]) % HASHSIZE; return c; } int insert(int t, int cur) { int h = hash(v[t].s); int u = head[cur][h]; while(u != -1) { if (memcmp(v[t].s, v[u].s, sizeof(v[t].s)) == 0) return 0; u = next[cur][u]; } next[cur][t] = head[cur][h]; head[cur][h] = t; return 1; } int search(int pos) { int h = hash(v[pos].s); int u = head[1][h]; while (u != -1) { if (memcmp(v[u].s, v[pos].s, sizeof(v[pos].s)) == 0) return u; u = next[1][u]; } return -1; } void show1(int pos) { if (v[pos].l == -1) return; show1(v[pos].l); printf("%d", v[pos].len); } void show2(int pos) { if (v[pos].l == -1) return; if(v[pos].len>2) printf("%d", v[pos].len-2 ); else printf("%d", v[pos].len +2); show2(v[pos].l); } void bfs(int cur) { way tmpway, newway; memcpy(v[front].s, a, sizeof(v[front].s)); v[front].l = -1; v[front].step = v[front].len = 0; insert(front, cur); while (front < rear) { tmpway = v[front]; if (!cur && (mid = search(front)) != -1) { show1(front); show2(mid); printf("\n"); flag=1; return; } if (tmpway.step <8) for(int i=1; i<=4; i++) { newway = tmpway; newway.l = front; newway.step++; newway.len = i; int temp1, temp2; if(i==1) { temp1 = newway.s[10]; temp2 = newway.s[11]; for (int i = 9; i >= 0; i--) newway.s[i + 2] = newway.s[i]; newway.s[0] = temp1; newway.s[1] = temp2; } else if(i==2) { temp1 = newway.s[9]; temp2 = newway.s[10]; for (int i = 9; i < 19; i++) newway.s[i] = newway.s[i + 2]; newway.s[20] = temp2; newway.s[19] = temp1; } else if(i==3) { temp1 = newway.s[0]; temp2 = newway.s[1]; for (int i = 2; i < 12; i++) newway.s[i - 2] = newway.s[i]; newway.s[10] = temp1; newway.s[11] = temp2; } else { temp1 = newway.s[19]; temp2 = newway.s[20]; for (int i = 18; i >= 9; i--) newway.s[i + 2] = newway.s[i]; newway.s[9] = temp1; newway.s[10] = temp2; } v[rear] = newway; if (insert(rear, cur)) rear++; } front++; } } int main() { int n; #ifndef ONLINE_JUDGE freopen("a.txt", "r", stdin); #endif scanf("%d", &n); memset(head, -1, sizeof(head)); memset(next,0,sizeof(next)); front =0; rear = 1; memcpy(a, target, sizeof(target)); bfs(1); int score1=front,score2=rear; while (n--) { for (int i = 0; i < 24; i++) scanf("%d", &a[i]); memset(head[0], -1, sizeof(head[0])); memset(next[0],0,sizeof(next[0])); if(memcmp(a,target,sizeof(target))==0) printf("PUZZLE ALREADY SOLVED\n"); else { front=score1; rear=score2+1; flag=0; bfs(0); if(!flag) printf("NO SOLUTION WAS FOUND IN 16 STEPS\n"); } } return 0; }
作者:moyan_min 发表于2012-12-25 19:46:43 原文链接
阅读:43 评论:0 查看评论