題意:

有個有很多珠子的遊戲,可以轉左邊/右邊/全部,然後順時針/逆時針轉

問說起始狀態轉到某個狀態需要幾步

題目有說會在20步內

 

解法:

做雙向BFS;先把從起始狀態走10部內的狀態都建好,之後從終點狀態走,看有沒有撞到從起點開始走的狀態

有的話就把兩邊步數相加就是答案

 

程式碼:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define HASH_SIZE 1234567
#define QUEUE_SIZE 3378183

struct Hash{
    long long int state;
    char step;
    struct Hash *next;
}h[HASH_SIZE],h2[HASH_SIZE],*q[QUEUE_SIZE+10];
int qNum;

void initialHashTable(struct Hash h[]){
    int i;
    struct Hash *cur,*tmp;
    for(i=0;i<HASH_SIZE;++i){
        cur = h[i].next;
        while(cur!=NULL){
            tmp = cur;
            cur = cur->next;
            free(tmp);
        }
        h[i].next = NULL;
    }
}

#define hashFun(key)(key%HASH_SIZE)
/*
int hashFun(long long int key){
    return key % HASH_SIZE;
}
*/
long long int stateToKey(char state[]){
    int i;
    long long int num=0;
    for(i=0;i<12;++i){
        num = num*13+state[i];
    }
    return num;
}
void keyToState(long long int key,char state[]){
    int i;
    for(i=0;i<12;++i){
        state[11-i] = key%13;
        key/=13;
    }
    state[12] = '\0';
}
struct Hash* search(struct Hash h[],char state[]){
    long long int key = stateToKey(state);
    struct Hash *cur = h[hashFun(key)].next;
    while(cur != NULL && cur->state!=key){
        cur = cur->next;
    }
    return cur;
}

struct Hash* insert(struct Hash h[],char state[],int step){
    long long int key = stateToKey(state);
    struct Hash *head = &h[hashFun(key)];
    struct Hash *cur = (struct Hash *)malloc(sizeof(struct Hash));
    cur->state = key;
    cur->step = step;
    cur->next = head->next;
    head->next = cur;
    return cur;
}

void input(char state[]){
    int i;
    int num;
    for(i=0;i<12;++i){
        scanf("%d",&num);
        state[i] = (char)(num);
    }
    state[12] = '\0';
}
void turnAllC(char state[],char next[]){
    next[0] = state[1];
    next[1] = state[2];
    next[2] = state[3];
    next[3] = state[4];
    next[4] = state[5];
    next[5] = state[6];
    next[6] = state[7];
    next[7] = state[8];
    next[8] = state[9];
    next[9] = state[10];
    next[10] = state[11];
    next[11] = state[0];
}
void turnAllCC(char state[],char next[]){
    next[0] = state[11];
    next[1] = state[0];
    next[2] = state[1];
    next[3] = state[2];
    next[4] = state[3];
    next[5] = state[4];
    next[6] = state[5];
    next[7] = state[6];
    next[8] = state[7];
    next[9] = state[8];
    next[10] = state[9];
    next[11] = state[10];
}
void turnRightC(char state[],char next[]){
    next[11] = state[5];
    next[10] = state[11];
    next[9] = state[10];
    next[8] = state[9];
    next[7] = state[8];
    next[6] = state[7];
    next[5] = state[6];
    next[4] = state[4];
    next[3] = state[3];
    next[2] = state[2];
    next[1] = state[1];
    next[0] = state[0];
}
void turnRightCC(char state[],char next[]){
    next[11] = state[10];
    next[10] = state[9];
    next[9] = state[8];
    next[8] = state[7];
    next[7] = state[6];
    next[6] = state[5];
    next[5] = state[11];
    next[4] = state[4];
    next[3] = state[3];
    next[2] = state[2];
    next[1] = state[1];
    next[0] = state[0];
}
void turnLeftC(char state[],char next[]){
    next[0] = state[1];
    next[1] = state[2];
    next[2] = state[3];
    next[3] = state[4];
    next[4] = state[5];
    next[5] = state[11];
    next[6] = state[6];
    next[7] = state[7];
    next[8] = state[8];
    next[9] = state[9];
    next[10] = state[10];
    next[11] = state[0];
}
void turnLeftCC(char state[],char next[]){
    next[0] = state[11];
    next[1] = state[0];
    next[2] = state[1];
    next[3] = state[2];
    next[4] = state[3];
    next[5] = state[4];
    next[6] = state[6];
    next[7] = state[7];
    next[8] = state[8];
    next[9] = state[9];
    next[10] = state[10];
    next[11] = state[5];
}

void printState(char state[]){
    int i;
    for(i=0;state[i]!='\0';++i)printf("%d ",state[i]);
    puts("");
}
void (*transF[6])(char*,char*)={turnAllC,turnAllCC,turnRightC,turnRightCC,turnLeftC,turnLeftCC};

void initialBFS(char state[]){
    int i,j;
    char next[13];
    initialHashTable(h);
    state[12] = '\0';
    q[0] = insert(h,state,0);
    qNum = 1;
    for(i=0;q[i]->step<10;++i){
        keyToState(q[i]->state,state);
        for(j=0;j<6;++j){
            transF[j](state,next);
            if(search(h,next)==NULL){
                q[qNum++] = insert(h,next,q[i]->step+1);
            }
        }
    }
}
int BFS(char state[]){
    int i,j;
    struct Hash *cur;
    char next[13];
    initialHashTable(h2);
    state[12] = '\0';
    if((cur=search(h,state))!=NULL){
        return cur->step;
    }else {
        q[0] = insert(h2,state,-1);
    }
    qNum = 1;
    for(i=0;i<qNum;++i){
        keyToState(q[i]->state,state);
        for(j=0;j<6;++j){
            transF[j](state,next);
            if((cur=search(h,next))!=NULL){
                return cur->step - q[i]->step;
            }else if((cur=search(h2,next))==NULL){
                q[qNum++] = insert(h2,next,q[i]->step-1);
            }
        }
    }
    return -1;
}
int main(){
    int t;
    char state[13]={1,2,3,4,5,6,7,8,9,10,11,12,'\0'};
    memset(h,0,sizeof(h));
    memset(h2,0,sizeof(h2));
    initialBFS(state);
    scanf("%d",&t);
    while(t--){
        input(state);
        printf("%d\n",BFS(state));
    }
    return 0;
}


arrow
arrow
    全站熱搜

    alan790712 發表在 痞客邦 留言(0) 人氣()