[usaco] 4.4.1PROB Shuttle Puzzle

 
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");
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章