Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
双向BFS~0ms,oh yeah!第一次用双向BFS,要不是不知道那个讨厌的strrev不能用的话就1A了…… 具体的标记可以这样实现: 标记栏设为短整型。对于从原始结果正着搜的,在标记时用队列数组下标表示;对于从最终结果逆着搜的,用下标的相反数表示。这样就可以将两路队列不同的搜索结果区分开了。 晒一下代码:(有点长,凑活看吧) //Single BFS <Memory: 4536K Time: 313ms> //POJ 1077 Eight //BFS: mark with sequence number //DBFS: mark in both way #include<iostream> #include<cstring> #include<cassert> #define DEST 46233 //The sequence num of "123456780",the destination using namespace std; struct Result{ char status[10]; short xPos; //Current position of x char move[50]; //record the current searching record! Important }; Result queue1[25000] = {0},*p1 = queue1,*q1 = queue1 + 1; Result queue2[25000] = {{"123456780",8,"\0"}},*p2 = queue2,*q2 = queue2 + 1; char Forward[50] = {0},Backward[50] = {0}; static short used[362881] = {false}; //to mark the searching sequence //now: the position of q (q1 == queue1 + now1) int count1 = 1,count2 = 1,now1 = 1,now2 = 1; int SequenceNum(const Result* m){ int big[9] = {0},sum = 0; for(int i = 0;i < 8;++i){ for(int j = i + 1;j < 9;++j){ if(m->status[i] > m->status[j])++big[8-i]; } } int fac = 1; for(int i = 1;i < 9;++i){ sum += big[i] * fac; fac *= i + 1; } return sum; } void BFS(){ int step,pos,Snum; char temp; while(true){ /* queue1*/ assert(count1 < 24999); pos = p1->xPos; step = strlen(p1->move); //up if(pos > 2){ strcpy(q1->status,p1->status); temp = q1->status[pos]; q1->status[pos] = q1->status[pos - 3]; q1->status[pos - 3] = temp; q1->xPos = pos - 3; Snum = SequenceNum(q1); //queue1 is positive queue2 is negative 0 means unsearched if(used[Snum] <= 0){ strcpy(q1->move,p1->move); q1->move[step] = 'u'; if(used[Snum] < 0){ strcpy(Forward,q1->move); strcpy(Backward,(queue2+(-used[Snum]))->move); return; } else{ used[Snum] = now1; //mark a positive number ++q1,++now1,++count1; if(q1 == queue1 + 25000)q1 = queue1+1,now1 = 1; } } } //down if(pos < 6){ strcpy(q1->status,p1->status); temp = q1->status[pos]; q1->status[pos] = q1->status[pos + 3]; q1->status[pos + 3] = temp; q1->xPos = pos + 3; Snum = SequenceNum(q1); //queue1 is positive queue2 is negative 0 means unsearched if(used[Snum] <= 0){ strcpy(q1->move,p1->move); q1->move[step] = 'd'; if(used[Snum] < 0){ strcpy(Forward,q1->move); strcpy(Backward,(queue2+(-used[Snum]))->move); return; } else{ used[Snum] = now1; //mark a positive number ++q1,++now1,++count1; if(q1 == queue1 + 25000)q1 = queue1+1,now1 = 1; } } } //left if(pos%3 > 0){ strcpy(q1->status,p1->status); temp = q1->status[pos]; q1->status[pos] = q1->status[pos - 1]; q1->status[pos - 1] = temp; q1->xPos = pos - 1; Snum = SequenceNum(q1); //queue1 is positive queue2 is negative 0 means unsearched if(used[Snum] <= 0){ strcpy(q1->move,p1->move); q1->move[step] = 'l'; if(used[Snum] < 0){ strcpy(Forward,q1->move); strcpy(Backward,(queue2+(-used[Snum]))->move); return; } else{ used[Snum] = now1; //mark a positive number ++q1,++now1,++count1; if(q1 == queue1 + 25000)q1 = queue1+1,now1 = 1; } } } //right if(pos%3 < 2){ strcpy(q1->status,p1->status); temp = q1->status[pos]; q1->status[pos] = q1->status[pos + 1]; q1->status[pos + 1] = temp; q1->xPos = pos + 1; Snum = SequenceNum(q1); //queue1 is positive queue2 is negative 0 means unsearched if(used[Snum] <= 0){ strcpy(q1->move,p1->move); q1->move[step] = 'r'; if(used[Snum] < 0){ strcpy(Forward,q1->move); strcpy(Backward,(queue2+(-used[Snum]))->move); return; } else{ used[Snum] = now1; //mark a positive number ++q1,++now1,++count1; if(q1 == queue1 + 25000)q1 = queue1+1,now1 = 1; } } } //p1 is over if(++p1 == queue1 + 25000)p1 = queue1+1; --count1; /* queue2 */ assert(count2 < 24999); pos = p2->xPos; step = strlen(p2->move); //up if(pos > 2){ strcpy(q2->status,p2->status); temp = q2->status[pos]; q2->status[pos] = q2->status[pos - 3]; q2->status[pos - 3] = temp; q2->xPos = pos - 3; Snum = SequenceNum(q2); //queue1 is positive queue2 is negative 0 means unsearched if(used[Snum] >= 0){ strcpy(q2->move,p2->move); q2->move[step] = 'd'; //searching backward,the move is the opposite if(used[Snum] > 0){ strcpy(Forward,(queue1 + used[Snum])->move); strcpy(Backward,q2->move); return; } else{ used[Snum] = -now2; //mark a negative number ++q2,++now2,++count2; if(q2 == queue2 + 25000)q2 = queue2+1,now2 = 1; } } } //down if(pos < 6){ strcpy(q2->status,p2->status); temp = q2->status[pos]; q2->status[pos] = q2->status[pos + 3]; q2->status[pos + 3] = temp; q2->xPos = pos + 3; Snum = SequenceNum(q2); //queue1 is positive queue2 is negative 0 means unsearched if(used[Snum] >= 0){ strcpy(q2->move,p2->move); q2->move[step] = 'u'; if(used[Snum] > 0){ strcpy(Forward,(queue1 + used[Snum])->move); strcpy(Backward,q2->move); return; } else{ used[Snum] = -now2; //mark a negative number ++q2,++now2,++count2; if(q2 == queue2 + 25000)q2 = queue2+1,now2 = 1; } } } //left if(pos%3 > 0){ strcpy(q2->status,p2->status); temp = q2->status[pos]; q2->status[pos] = q2->status[pos - 1]; q2->status[pos - 1] = temp; q2->xPos = pos - 1; Snum = SequenceNum(q2); //queue1 is positive queue2 is negative 0 means unsearched if(used[Snum] >= 0){ strcpy(q2->move,p2->move); q2->move[step] = 'r'; if(used[Snum] > 0){ strcpy(Forward,(queue1+used[Snum])->move); //bug1 detected:q1->queue1 strcpy(Backward,q2->move); return; } else{ used[Snum] = -now2; //mark a negative number ++q2,++now2,++count2; if(q2 == queue2 + 25000)q2 = queue2+1,now2 = 1; } } } //right if(pos%3 < 2){ strcpy(q2->status,p2->status); temp = q2->status[pos]; q2->status[pos] = q2->status[pos + 1]; q2->status[pos + 1] = temp; q2->xPos = pos + 1; Snum = SequenceNum(q2); //queue1 is positive queue2 is negative 0 means unsearched if(used[Snum] >= 0){ strcpy(q2->move,p2->move); q2->move[step] = 'l'; if(used[Snum] > 0){ strcpy(Forward,(queue1+used[Snum])->move); strcpy(Backward,q2->move); return; } else{ used[Snum] = -now2; //bug2 detected: negative number ++q2,++now2,++count2; if(q2 == queue2 + 25000)q2 = queue2+1,now2 = 1; } } } //p1 is over if(++p2 == queue2 + 25000)p2 = queue2+1; --count2; } } int main(){ /* Get the original board */ for(int i = 0;i < 9;++i){ cin>>p1->status[i]; if(p1->status[i] == 'x'){ p1->status[i] = '0'; p1->xPos = i; } } int reversepair = 0; for(int i = 0;i < 8;++i){ for(int j = i + 1;j < 9;++j){ if(p1->status[i] == '0' || p1->status[j] == '0')continue; if(p1->status[i] < p1->status[j])++reversepair; } } if(reversepair%2){ printf("unsolvable!\n"); system("PAUSE"); return 0; } if(strcmp(p1->status,"123456780") == 0){ printf("0\n"); return 0; } used[SequenceNum(p1)] = 30000; //mark first used[DEST] = -30000; memset(p1->move,0,100*sizeof(char)); /* Search and print result */ BFS(); strrev(Backward); printf("%s%s\n",Forward,Backward); cin.get(); cin.get(); return 0; } /* 1 2 3 4 5 6 x 7 8 2 rr 1 2 3 4 8 5 x 7 6 4 rurd 2 3 6 1 5 8 4 7 x 8 uullddrr 8 6 7 2 5 4 3 x 1 ************* Standard Output ***************** 49 ruullddrruullddrruullddrruldrulurddlurulddrulurdd ************* My BFS Program puts ***************** 31 uulddrruuldldrruuldldrruullddrr correct ************* My DBFS Program puts ***************** 31 ruulddruuldldrrullurrdlldruurdd correct 2 3 4 1 5 x 7 6 8 ************* Standard Output ***************** ullddrurdllur druldr ************* My Program puts ***************** ullddrurdllur rdlurd correct 7 3 8 x 2 6 1 5 4 rrullddrrululdrdlurdr 7 3 6 x 2 8 1 5 4 Assertion failed! why? 87654321x ulldruurddluuld druurddluuldrrd correct 12345687x(Unsolvable) uulddlurrullddruldrrululdddldldrurullddrurdluurdllurdrd wrong */ Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator