uva704 - Colour Hash(彩色转盘)

来源:互联网 发布:axl rose肥了 知乎 编辑:程序博客网 时间:2024/05/29 18:34

和大多数ACMer一样,一开始,我习惯性的单项搜索,结果搞了一下午没搞出来,

看了人家的思路,我明白了单向搜16层是多么的可笑啊, 就算把数组开到最大也是不够用的。。。。

正确的做法应该是双向搜索 

这样写了以后,我又呆了,还是不对,我忽略了逆向搜索输出路径是应该也是逆向的,就是说如果原来是逆向3搜过来的,输出是应该是输出3的逆向,就是1。

这是我做过搜索中少有的代码超长的题目,有点力不从心啊,

代码如下:

#include <cstdio>#include <cstring>#define MN 100003using namespace std;int ok, ans, ans2, head[MN], next[MN], fa[MN], pa[MN], step[MN];int back_st[MN][24], st[MN][24], sta[24], _aim[24] = {0,3,4,3,0,5,6,5,0,1,2,1,0,7,8,7,0,9,10,9,0};int back_head[MN], back_next[MN], back_fa[MN], back_pa[MN];int is_ok(){    for(int i = 0; i < 21; i++) if(sta[i]!=_aim[i]) return 0;    return 1;}int _strcmp(int *a, int *b){    for(int i = 0; i < 21; i++) if(a[i]!=b[i]) return 0;    return 1;}int hash(int cur){    int s = 0;    for(int i = 0; i < 2l; i++)        s = (s * 11 + st[cur][i])%MN;    return s;}int is_succeed(int cur){    int h = hash(cur);    int u = back_head[h];    while(u)    {        if(_strcmp(back_st[u],st[cur])) { ans2 = u; return 1;}        u = back_next[u];    }    return 0;}int try_to_insert(int cur){    int h = hash(cur);    int u = head[h];    while(u)    {        if(_strcmp(st[cur],st[u])) return 0;        u = next[u];    }    next[cur] = head[h];    head[h] = cur;    return 1;}void bfs(int *A, int state){    int rear = 0, front = 1;    step[0] = 0;    for(int i = 0; i < 21; i++) st[0][i] = A[i];    memset(head,0,sizeof(head));    memset(next,0,sizeof(next));    try_to_insert(0);    while(rear<front)    {        if(state>0&&is_succeed(rear)) { ok = 1; ans = rear; break; }        if(step[rear]>8) break;        for(int i = 0; i <= 9; i++) st[front][i+2] = st[rear][i];        st[front][0] = st[rear][10];    st[front][1] = st[rear][11];        for(int i = 12; i <= 20; i++) st[front][i] = st[rear][i];        if(try_to_insert(front)) {step[front] = step[rear]+1; pa[front] = 1; fa[front] = rear; front++;}        for(int i = 9; i <= 18; i++) st[front][i] = st[rear][i+2];        st[front][19] = st[rear][9];    st[front][20] = st[rear][10];        for(int i = 0; i <= 8; i++) st[front][i] = st[rear][i];        if(try_to_insert(front)) {step[front] = step[rear]+1; pa[front] = 2; fa[front] = rear; front++;}        for(int i = 0; i <= 9; i++) st[front][i] = st[rear][i+2];        st[front][10] = st[rear][0];    st[front][11] = st[rear][1];        for(int i = 12; i <= 20; i++) st[front][i] = st[rear][i];        if(try_to_insert(front)) {step[front] = step[rear]+1; pa[front] = 3; fa[front] = rear; front++;}        for(int i = 9; i <= 18; i++) st[front][i+2] = st[rear][i];        st[front][9] = st[rear][19];    st[front][10] = st[rear][20];        for(int i = 0; i <= 8; i++) st[front][i] = st[rear][i];        if(try_to_insert(front)) {step[front] = step[rear]+1; pa[front] = 4; fa[front] = rear; front++;}        rear++;    }}void print_path(int cur){    if(!cur) return;    print_path(fa[cur]);    printf("%d",pa[cur]);}void back_print_path(int cur){    if(!cur) return;    if(back_pa[cur]==1)printf("3");    else if(back_pa[cur]==3)printf("1");    else if(back_pa[cur]==2)printf("4");    else if(back_pa[cur]==4)printf("2");    back_print_path(back_fa[cur]);}int main (){    int t;    scanf("%d",&t);    bfs(_aim,-1);    memcpy(back_head,head,sizeof(head));    memcpy(back_next,next,sizeof(next));    memcpy(back_fa,fa,sizeof(fa));    memcpy(back_pa,pa,sizeof(pa));    memcpy(back_st,st,sizeof(st));    while(t--)    {        for(int i = 0; i < 24; i++)  scanf("%d",&sta[i]);        if(is_ok()) { puts("PUZZLE ALREADY SOLVED"); continue; }        ans = ans2 = 0; ok = 0; bfs(sta,1);        if(ok) { print_path(ans); back_print_path(ans2); printf("\n");}        else puts("NO SOLUTION WAS FOUND IN 16 STEPS");    }    return 0;}


原创粉丝点击