Shuttle Puzzle
Traditional
The Shuttle Puzzle of size 3 consists of 3 white marbles, 3 black marbles, and a strip of wood with 7 holes. The marbles of the same color are placed in the holes at the opposite ends of the strip, leaving the center hole empty.
INITIAL STATE: WWW_BBB
GOAL STATE: BBB_WWW
To solve the shuttle puzzle, use only two types of moves. Move 1 marble 1 space (into the empty hole) or jump 1 marble over 1 marble of the opposite color (into the empty hole). You may not back up, and you may not jump over 2 marbles.
A Shuttle Puzzle of size N consists of N white marbles and N black marbles and 2N+1 holes.
Here's one solution for the problem of size 3 showing the initial, intermediate, and end states:
WWW BBB
WW WBBB
WWBW BB
WWBWB B
WWB BWB
W BWBWB
WBWBWB
BW WBWB
BWBW WB
BWBWBW
BWBWB W
BWB BWW
B BWBWW
BB WBWW
BBBW WW
BBB WWW
Write a program that will solve the SHUTTLE PUZZLE for any size N (1 <= N <= 12) in the minimum number of moves and display the successive moves, 20 per line.
PROGRAM NAME: shuttle
INPUT FORMAT
A single line with the integer N.
SAMPLE INPUT (file shuttle.in)
3
OUTPUT FORMAT
The list of moves expressed as space-separated integers, 20 per line (except possibly the last line). Number the marbles/holes from the left, starting with one.
Output the the solution that would appear first among the set of minimal solutions sorted numerically (first by the first number, using the second number for ties, and so on).
SAMPLE OUTPUT (file shuttle.out)
3 5 6 4 2 1 3 5 7 6 4 2 3 5 4
--------------------------------------------------------------------------------
好奇怪的一道题。
主要算法是bfs。
主要有四种情况需要处理。
W_B->_WB
W_B->WB_
_WB->BW_
WB_->_BW
所以对于一个状态,只需要处理这四种情况就可以了。
不过好奇怪,我把hash开得很大的时候,说资源超限,然后改小了,奇迹般的过了。
但是对于超过10的情况,我的机器还是跑不出来(超过了5s),不知道usaco是什么样的神奇的机器,竟然可以在0.几秒内跑出来。
USER: Ma yunlei [yunleis2]
TASK: shuttle
LANG: C++
Compiling...
Compile: OK
Executing...
Test 1: TEST OK [0.000 secs, 3376 KB]
Test 2: TEST OK [0.000 secs, 3376 KB]
Test 3: TEST OK [0.000 secs, 3376 KB]
Test 4: TEST OK [0.000 secs, 3376 KB]
Test 5: TEST OK [0.000 secs, 3376 KB]
Test 6: TEST OK [0.000 secs, 3384 KB]
Test 7: TEST OK [0.000 secs, 3384 KB]
Test 8: TEST OK [0.027 secs, 3384 KB]
Test 9: TEST OK [0.108 secs, 3384 KB]
Test 10: TEST OK [0.243 secs, 3384 KB]
All tests OK.
Your program ('shuttle') produced all correct answers! This is your
submission #6 for this problem. Congratulations!
Here are the test data inputs:
------- test 1 ----
1
------- test 2 ----
3
------- test 3 ----
4
------- test 4 ----
5
------- test 5 ----
7
------- test 6 ----
8
------- test 7 ----
9
------- test 8 ----
10
------- test 9 ----
11
------- test 10 ----
12
/* ID:yunleis3 PROG:shuttle LANG:C++ */ #include <fstream> #include<iostream> #include<queue> using namespace std; const int maxn=13; int n; const int black=3; const int white=2; const int blank=1; const int maxnhash=167216; bool hash1[maxnhash]; bool hash2[maxnhash]; unsigned long elf_hash(const char *name) { unsigned long h = 0, g; while (*name) { h = (h << 4) + *name++; if (g = h & 0xf0000000) h ^= g >> 24; h &= ~g; } return h; } class step{ public : queue<int> steps; char state[2*maxn+1]; int ptr; step operator =(step &s){ steps=s.steps; for(int i=0;i<=2*n+1;++i){ this->state[i]=s.state[i]; } return * this; } }; inline void swap(char *a,char *b){ char x=*a; *a=*b; *b=x; } inline void myhash(const char * ch,unsigned &ha1,unsigned ha2){ unsigned result=0; int end=2*n+1; ha1=0; for(int i=0;i<n;++i){ ha1<<=2; ha1+=ch[i]; } ha2=0; for(int i=n;i<end;++i){ ha2<<=2; ha2+=ch[i]; } } int main(){ ifstream fin("shuttle.in"); fin>>n; step init; step rs; queue<step> result; for(int i=0;i<n;i++){ init.state[i]=white; } init.state[n]=blank; for(int i=n+1;i<2*n+1;i++){ init.state[i]=black; } init.ptr=n; init.state[2*n+1]='\0'; queue<step> q; q.push(init); while(!q.empty()){ step s=q.front(); q.pop(); //check static unsigned h1; static unsigned h2; myhash(s.state,h1,h2); h1%=maxnhash; h2%=maxnhash; if(hash1[h1]&&hash2[h2]) { //cout<<"mark"<<endl;; continue; } hash1[h1]=true; hash1[h2]=true; if(s.ptr==n){ bool flag=true; for(int i=0;flag&&i<n;i++){ if(s.state[i]==white) flag=false; } for(int i=n+1;flag&&i<2*n+1;i++){ if(s.state[i]==black) flag=false; } if(flag){ rs=s;//result.push(s); break; } } if((s.ptr-1)>=0&&s.state[s.ptr-1]==white){ step s1=s; swap(s1.state+s1.ptr-1,s1.state+s1.ptr); --s1.ptr; s1.steps.push(s1.ptr); q.push(s1); } if((s.ptr-2)>=0&&s.state[s.ptr-2]==white&&s.state[s.ptr-1]==black){ step s2=s; swap(s2.state+s2.ptr-2,s2.state+s2.ptr); --(--s2.ptr); s2.steps.push(s2.ptr); q.push(s2); } if((s.ptr+1)<(2*n+1)&&s.state[s.ptr+1]==black){ step s3=s; swap(s3.state+s3.ptr+1,s3.state+s3.ptr); ++s3.ptr; s3.steps.push(s3.ptr); q.push(s3); } if((s.ptr+2)<(2*n+1)&&s.state[s.ptr+2]==black&&s.state[s.ptr+1]==white){ step s4=s; swap(s4.state+s4.ptr+2,s4.state+s4.ptr); ++(++s4.ptr); s4.steps.push(s4.ptr); q.push(s4); } } queue<int> q1=rs.steps; int ptr=0; ofstream fout("shuttle.out"); while(!q1.empty()){ fout<<q1.front()+1;//<<" "; q1.pop(); if(q1.empty()) break; if((++ptr)==20) { fout<<endl; ptr=0; } else fout<<" "; } fout<<endl; //system("pause"); }