思路:
源自:田益铭的BLOG 这道题做的很崩,勉强做出来居然过掉了。不过以后就会写简单的路径存储了。 BFS,6入口,记录路径。 突然发现BFS也不需要优先队列啊…普通队列就行了呀。 第一次做记录路径的搜索,总结如下:
结构体要保存:状态 (x,y),深度 (step),前驱 (pre)。 需要一个数组 存储 pot ,什么时候用呢,就是当丢掉一个 pot 时紧接着存起来就可以了。 发现带有构造函数的结构体不能使用数组。 需要一个栈 来实现反向输出。
代码:
#include <iostream>
#include <queue>
#include <cstring>
#include <stack>
using namespace std;
const int maxn = 105 ;
bool vis[ maxn] [ maxn] ;
bool ok = false;
int A, B, C;
struct pot{
int x, y;
int step;
int ope;
int pre;
} ;
pot path[ maxn * maxn] ; int cnt = 1 ;
queue< pot> Q;
int theend;
int ans;
stack< int > S;
void Mypush ( int x, int y, int step, int ope, int pre) {
pot temp;
temp. x = x;
temp. y = y;
temp. step = step;
temp. ope = ope;
temp. pre = pre;
Q. push ( temp) ;
return ;
}
void Stretch ( pot cur) {
for ( int i= 1 ; i<= 6 ; i++ ) {
int x , y;
int step ;
switch ( i)
{
case 1 :
x = A , y = cur. y; break ;
case 2 :
x = cur. x , y = B; break ;
case 3 :
x = 0 , y = cur. y; break ;
case 4 :
x = cur. x , y = 0 ; break ;
case 5 :
if ( cur. x + cur. y <= B)
x = 0 , y = cur. x + cur. y;
else
x = cur. x + cur. y - B , y = B;
break ;
case 6 :
if ( cur. x + cur. y <= A)
x = cur. x + cur. y , y = 0 ;
else
x = A , y = cur. x + cur. y - A;
break ;
}
step = cur. step + 1 ;
if ( vis[ x] [ y] )
continue ;
vis[ x] [ y] = true;
Mypush ( x , y , step , i , cnt- 1 ) ;
}
return ;
}
void BFS ( ) {
Mypush ( 0 , 0 , 0 , 0 , 0 ) ;
vis[ 0 ] [ 0 ] = true;
while ( ! Q. empty ( ) ) {
pot cur = Q. front ( ) ; Q. pop ( ) ;
path[ cnt++ ] = cur;
if ( cur. x == C || cur. y == C) {
ok = true;
theend = cnt- 1 ;
ans = cur. step;
return ;
}
Stretch ( cur) ;
}
return ;
}
void Output ( ) {
if ( ! ok) {
cout<< "impossible" << endl;
return ;
}
cout<< ans<< endl;
pot cur= path[ theend] ;
while ( cur. pre) {
S. push ( cur. ope) ;
cur = path[ cur. pre] ;
}
while ( S. size ( ) ) {
int i = S. top ( ) ; S. pop ( ) ;
switch ( i) {
case 1 : cout<< "FILL(1)" << endl; break ;
case 2 : cout<< "FILL(2)" << endl; break ;
case 3 : cout<< "DROP(1)" << endl; break ;
case 4 : cout<< "DROP(2)" << endl; break ;
case 5 : cout<< "POUR(1,2)" << endl; break ;
case 6 : cout<< "POUR(2,1)" << endl; break ;
}
}
return ;
}
int main ( ) {
cin>> A>> B>> C;
memset ( vis, false, sizeof ( vis) ) ;
BFS ( ) ;
Output ( ) ;
return 0 ;
}