编程半小时,差错8小时
#include<iostream>
#include<cstdio>
#include<map>
#include<stack>
using namespace std;
struct Node{
int id;
int k1,k2;
int pr;
int step;
int op;
}Q[110*110];
int visit[110][110];
int front,tail,A,B,C;
map<int,string> OP;
bool ok(int k1, int k2){
if(k1 < 0 || k2 < 0 || visit[k1][k2] || k1 > A || k2 > B)return false;
return true;
}
void push(int id, int k1, int k2, int pr, int step, int op){
Q[tail].id = id;
Q[tail].k1 = k1;
Q[tail].k2 = k2;
Q[tail].pr = pr;
Q[tail].step = step;
Q[tail++].op = op;
}
Node get_front(){
return Q[front];
}
void pop(){
front++;
}
bool empty(){
if(front < tail)return false;
return true;
}
void bfs(){
visit[0][0] = 1;
push(tail,0,0,-1,0,0);
Node t;
while(!empty()){
Node tem = get_front();
pop();
if(tem.k1 == C || tem.k2 == C){
stack<Node> T;
cout << tem.step << endl;
while(tem.pr != -1){
T.push(tem);
tem = Q[tem.pr];
}
while(!T.empty()){
tem = T.top();
T.pop();
cout << OP[tem.op] << endl;
}
return;
}
for(int i = 1;i <= 6;i++){
if(i == 1){ //FILL A
t.id = tail;
t.k1 = A;
t.k2 = tem.k2;
t.op = 1;
t.pr = tem.id;
t.step = tem.step + 1;
}else if(i == 2){ //FILL B
t.id = tail;
t.k1 = tem.k1;
t.k2 = B;
t.op = 2;
t.pr = tem.id;
t.step = tem.step + 1;
}else if(i == 3){ //DROP A
t.id = tail;
t.k1 = 0;
t.k2 = tem.k2;
t.op = 3;
t.pr = tem.id;
t.step = tem.step + 1;
}else if(i == 4){ //DROP B
t.id = tail;
t.k1 = tem.k1;
t.k2 = 0;
t.op = 4;
t.pr = tem.id;
t.step = tem.step + 1;
}else if(i == 5){ // A -> B
if(tem.k1 + tem.k2 <= B){
t.id = tail;
t.k1 = 0;
t.k2 = tem.k1 + tem.k2;
t.op = 5;
t.pr = tem.id;
t.step = tem.step + 1;
}else{
t.id = tail;
t.k1 = tem.k1 + tem.k2 - B;
t.k2 = B;
t.op = 5;
t.pr = tem.id;
t.step = tem.step + 1;
}
}else if(i == 6){ // B -> A
if(tem.k1 + tem.k2 <= A){
t.id = tail;
t.k1 = tem.k1 + tem.k2;
t.k2 = 0;
t.op = 6;
t.pr = tem.id;
t.step = tem.step + 1;
}else{
t.id = tail;
t.k1 = A;
t.k2 = tem.k1 + tem.k2 - A;
t.op = 6;
t.pr = tem.id;
t.step = tem.step + 1;
}
}
//这样的方式,前面将遍历每一种情况,最后得到新的k1与k2,然后判断k1与k2是否合法,合法即加入队列
if(ok(t.k1,t.k2)){
push(t.id, t.k1, t.k2, t.pr, t.step, t.op);
visit[t.k1][t.k2] = 1;
}
}
}
puts("impossible"); //队列为空时,代表遍历了所有情况,都不能找到目标解,因此输出impossible
}
void init(){
front = tail = 0;
for(int i = 0;i < 110;i++){
for(int j = 0 ;j < 110;j++){
visit[i][j] = 0;
}
}
}
int main(){
OP[0] = "NONE"; //不会输出,无实际意义
OP[1] = "FILL(1)";
OP[2] = "FILL(2)";
OP[3] = "DROP(1)";
OP[4] = "DROP(2)";
OP[5] = "POUR(1,2)";
OP[6] = "POUR(2,1)";
while(scanf("%d%d%d",&A,&B,&C) != EOF){ //OJ中以文件输入,当有多个输入例子时,必须以EOF进行判断
init();//每一次BFS前一定要初始化
bfs();
}
return 0;
}