POJ 3414 Pots

poj 3414 Pots

Description

You are given two pots, having the volume of A and B liters respectively. The following operations can be performed:

FILL(i) fill the pot i (1 ≤ i ≤ 2) from the tap;
DROP(i) empty the pot i to the drain;
POUR(i,j) pour from pot i to pot j; after this operation either the pot j is full (and there may be some water left in the pot i), or the pot i is empty (and all its contents have been moved to the pot j).
Write a program to find the shortest possible sequence of these operations that will yield exactly C liters of water in one of the pots.

Input

On the first and only line are the numbers A, B, and C. These are all integers in the range from 1 to 100 and C≤max(A,B).

Output

The first line of the output must contain the length of the sequence of operations K. The following K lines must each describe one operation. If there are several sequences of minimal length, output any one of them. If the desired result can’t be achieved, the first and only line of the file must contain the word ‘impossible’.

Sample Input

3 5 4

Sample Output

6
FILL(2)
POUR(2,1)
DROP(1)
POUR(2,1)
FILL(2)
POUR(2,1)

Source

Northeastern Europe 2002, Western Subregion

题目链接

题目大意:
给你三个数a,b,c 其中a,b代表两个容器的容量,一开始a和b为空。可通过四种操作(装满a/b、倒掉a/b、把a到给b、把b倒给a),注意:在a和b互相倒直至一方容器水满了或空了。倒出任何一个杯子中有c升水即成功,然后输出任意一种倒水顺序最少的过程及次数

题目思路:
很经典的bfs+回溯,回溯过程要注意状态结点必须动态申请并且将地址入队列。
(憨憨的我直接定义了一个结点,并把结点入队,回溯的时候发现pre地址无效。)
将(i,j)作为一种状态
初始:(0,0)
目标:(x,y)x= =c || y= =c
状态结束的条件:状态重复或者找到答案
紧接着就是模拟6种情况求解
通过栈和pre指针进行回溯得到解的过程

推荐一道类似的题目:HDU1495

代码:

#include
#include
#include
#include
#include
#include
using namespace std;
struct node {
     
	int i;	//i,j一起表示一种状态
	int j;
	int step;	//表示当前执行的是哪一步
	int cnt; //表示执行了多少步
	node* pre;	//回溯得到之间执行了哪些操作
	node(int i, int j, int step, int cnt) {
     
		this->i = i; this->j = j; this->step = step; this->cnt = cnt;
	}
};
int visit[105][105] = {
     0};	//记录当前状态是否到达过
char ope[6][12] = {
     "FILL(1)","FILL(2)","DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)"};
int a, b, c;
int flag = 0;

void print_ans(node * ans)
{
     
	stack<int> path;
	printf("%d\n", ans->cnt);
	while (ans->pre != NULL)
	{
     
		path.push(ans->step);
		ans = ans->pre;
	}	
	while (!path.empty())
	{
     
		int t = path.top();
		path.pop();
		printf("%s\n", ope[t-1]);
	}
}
void bfs()
{
     
	queue<node*> q;
	node *x =new node(0, 0, 0, 0);
	x->pre = NULL;
	q.push(x);
	visit[0][0] = 1;
	while (!q.empty())
	{
     
		node* t = q.front();
		q.pop();
		if (flag)return;	//找到答案过了
		if (t->i == c || t->j == c) {
     
			flag = 1;	//标记找到答案
			print_ans(t);
			return;
		}
		if (visit[a][t->j] == 0) {
     
			node* next1 =new node(a, t->j, 1, t->cnt + 1);
			next1->pre = t;
			visit[a][t->j] = 1;
			q.push(next1);
		}
		if (visit[t->i][b] == 0) {
     
			node *next2 = new node(t->i, b, 2, t->cnt + 1);
			next2->pre = t;
			visit[t->i][b] = 1;
			q.push(next2);
		}
		if (visit[0][t->j] == 0) {
     
			node *next3 = new node(0, t->j, 3, t->cnt + 1);
			next3->pre = t;
			visit[0][t->j] = 1;
			q.push(next3);
		}
		if (visit[t->i][0]==0) {
     
			node *next4 = new node(t->i, 0, 4, t->cnt + 1);
			next4->pre = t;
			visit[t->i][0] = 1;
			q.push(next4);
		}
		int s = t->i + t->j;
		int ii, jj;
		//i->j
		if (!(t->i == 0 || t->j == b)) {
     
			if (s - b > 0)ii = s - b, jj = b;
			else ii = 0, jj = s;
			if (visit[ii][jj] == 0) {
     
				node* next5=new node(ii, jj, 5, t->cnt + 1);
				next5->pre = t;
				visit[ii][jj] = 1;
				q.push(next5);
			}
		}

		//j->i
		if (!(t->i == a || t->j == 0)) {
     
			if (s - a > 0)jj = s - a, ii = a;
			else jj = 0, ii = s;
			if (visit[ii][jj] == 0) {
     
				node *next6=new node(ii, jj, 6, t->cnt + 1);
				next6->pre = t;
				visit[ii][jj] = 1;
				q.push(next6);
			}
		}
	}
}
int main()
{
     
	cin >> a >> b >> c;
	bfs();
	if (flag == 0)printf("impossible\n");
	return 0;
}

你可能感兴趣的:(bfs,&,dfs,OJ题解,算法,bfs)