POJ 3414

很经典的两个杯子互相倒水操作的问题

忍住不下意识点开discus,虽然有些不适应,不敢放开手脚,但是真正提升码力,做到写出来的代码能有自信和把握。

细节很多,审题极其重要

简单的BFS

#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <stack>
#include <map>
#include <set>
using namespace std;

const int HEAD= -1;
const int FILL_1= 0;
const int FILL_2= 1;
const int DROP_1= 2;
const int DROP_2= 3;
const int POUR_1_2= 4;
const int POUR_2_1= 5;
const int maxn= 105;

struct Node
{
	int l, r;
	Node(int _l= 0, int _r= 0) : l(_l), r(_r) {}
};
bool vis[maxn][maxn];
int op[maxn][maxn], dis[maxn][maxn];
int fa_l[maxn][maxn], fa_r[maxn][maxn];
int a, b, c;

Node BFS()
{
	if (0== c){
		return Node(0, 0);
	}
	queue<Node> Q;
	memset(vis, 0, sizeof(vis));
	vis[0][0]= 1;
	dis[0][0]= 0;
	fa_l[0][0]= 0;
	fa_r[0][0]= 0;
	op[0][0]= HEAD;
	Q.push(Node(0, 0));
	int l, r, v, p, q;

	while (!Q.empty()){
		Node cur= Q.front();
		Q.pop();
		l= cur.l;
		r= cur.r;
		v= dis[l][r]+1;
		
		for (int id= 0; id< 6; ++id){
			if (FILL_1== id){
				p= a;
				q= r;
			}
			else if (FILL_2== id){
				p= l;
				q= b;
			}
			else if (DROP_1== id){
				p= 0;
				q= r;
			}
			else if (DROP_2== id){
				p= l;
				q= 0;
			}
			else if (POUR_1_2== id){
				int t_sum= l+r;
				p= max(t_sum-b, 0);
				q= min(b, t_sum);
			}
			else if (POUR_2_1== id){
				int t_sum= l+r;
				p= min(a, t_sum);
				q= max(t_sum-a, 0);
			}

			if (!vis[p][q]){
				vis[p][q]= 1;
				dis[p][q]= v;
				fa_l[p][q]= l;
				fa_r[p][q]= r;
				op[p][q]= id;
				Q.push(Node(p, q));
			}
			if (p== c || q== c){
				return Node(p, q);
			}
		}
	}

	return Node(-1, -1);
}

int main(int argc, char const *argv[])
{
	scanf("%d %d %d", &a, &b, &c);
	Node res= BFS();
	stack<int> S;
	int l= res.l, r= res.r;

	if (-1== l && -1== r){
		printf("impossible");
	}
	else{
		while (0!= l || 0!= r){
			S.push(op[l][r]);
			int ll= fa_l[l][r], rr= fa_r[l][r];
			l= ll;
			r= rr;
		}
		printf("%d\n", dis[res.l][res.r]);
		while (!S.empty()){
			int cur= S.top();
			S.pop();
			switch(cur){
				case FILL_1:
					printf("FILL(1)\n");
					break;
				case FILL_2:
					printf("FILL(2)\n");
					break;
				case DROP_1:
					printf("DROP(1)\n");
					break;
				case DROP_2:
					printf("DROP(2)\n");
					break;
				case POUR_1_2:
					printf("POUR(1,2)\n");
					break;
				case POUR_2_1:
					printf("POUR(2,1)\n");
					break;
				default:
					break;
			}
		}
	}
	return 0;
}
posted @ 2021-04-20 12:47  IdiotNe  阅读(35)  评论(0编辑  收藏  举报