704 - Colour Hash

来源:互联网 发布:pc网络竞技游戏 编辑:程序博客网 时间:2024/06/05 13:22
描述:采用双广搜完成,因为单广搜层数太多,不但超时(结果根本出不来),而且还超内存(开不下这么大的数组),双广搜分为两部分,每部分的层数都为8层,分别是从开始的转轮和最终的转轮开始广搜,遇到重合了就可以输出路径,如果不重合,顶多两部分全都搜完,由于目标转轮是确定的,所以第一次的从目标转轮进行的广搜可以存储下来,以后只需要从开始的转轮广搜就可以了,这样可以节省时间。#include <stdio.h>#include <string.h>#define MAX 200000#define HASHSIZE 10000003struct 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;}