描述:采用双广搜完成,因为单广搜层数太多,不但超时(结果根本出不来),而且还超内存(开不下这么大的数组),双广搜分为两部分,每部分的层数都为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;
}
704 - Colour Hash
最新推荐文章于 2016-12-28 22:12:22 发布