POJ 3414倒水问题

编程半小时,差错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;
}

猜你喜欢

转载自blog.csdn.net/qq_40596572/article/details/103196215