USACO Training Section1.4 The Clocks

简单的用宽度优先搜索。状态空间的大小为4^9,性能上是可以接受的。考虑到每个时钟只有3,6,9,12四种状态,且目标状态为12,可将其转化为1230,这样,9个时钟可以放在一个整数的18位中,比较状态只需比较两个整数是否相等,而目标状态为0,更容易判断。

调试过程:turn函数中漏掉了cur >>= 2;导致状态不正确。

原题链接:
http://ace.delos.com/usacoprob2?a=1N7165lJnJE&S=clocks

/*
ID: blackco3
TASK: clocks
LANG: C++
*/
#include <fstream>
#include <iostream>
#include <stdlib.h>
#include <memory.h>

#define _max_states_ 1<<18
using namespace std ;
int trans[9][9] = {
/*	 A  B  C  D  E  F  G  H  I */
	{1, 1, 0, 1, 1, 0, 0, 0, 0 }, //ABDE
	{1, 1, 1, 0, 0, 0, 0, 0, 0 }, //ABC
	{0, 1, 1, 0, 1, 1, 0, 0, 0 }, //BCEF
	{1, 0, 0, 1, 0, 0, 1, 0, 0 }, //ADG
	{0, 1, 0, 1, 1, 1, 0, 1, 0 }, //BDEFH
	{0, 0, 1, 0, 0, 1, 0, 0, 1 }, //CFI
	{0, 0, 0, 1, 1, 0, 1, 1, 0 }, //DEGH
	{0, 0, 0, 0, 0, 0, 1, 1, 1 }, //GHI
	{0, 0, 0, 0, 1, 1, 0, 1, 1 }, //EFHI
};
int queue[_max_states_];
int visited[_max_states_];
struct t_trace{
	t_trace *pre ;
	int trans ;
} trace[_max_states_];
int source ;

void show_trace( ofstream &fout, t_trace *p_trace )
{
	if( p_trace->pre-trace==source ){
		fout << p_trace->trans  ;
		return ;
	}
	show_trace(fout, p_trace->pre );
	fout << " " << p_trace->trans  ;
}

int turn( int cur, int tno )
{
	int tmp, res=0 ;
	for( int i=0; i<9; i++){
		tmp = cur & 0x3 ;
		tmp = trans[tno][i] ? (tmp+1)&0x3 : tmp ;
		res |= tmp<<(i<<1);
		cur >>= 2 ;
	}
	return res ;
}

int main() {
    ofstream fout ("clocks.out");
    ifstream fin ("clocks.in");
	
	source=0;
	for( int i=0, tmp=0; i<9; i++ ){
		fin >> tmp ;
		source |= ((tmp/3)&0x3)<<(i<<1) ;
	}
	memset( visited, 0, sizeof(visited) );
	int *head=queue, *tail=queue; 
	*(tail++)=source , visited[source]=1 ;
	int next, unfound=1 ;
	do{
		for( int i=0; i<9; i++ ){
			next=turn(*head, i);
			if( visited[next] )
				continue ;
			visited[next]=1;
			*(tail++)=next ;
			trace[next].pre=trace+*head, trace[next].trans=i+1;
			if( !next ){
				unfound=0 ;
				break ;
			}
		}
	}while((++head)!=tail && unfound );
	show_trace(fout, trace);
	fout << endl ;
	return 0;
}

你可能感兴趣的:(C++,c,C#)