UVa 571 - Jugs

题目:给你两个杯子,每次可以给某个杯子灌满,清空,或者将一个杯子的水倒入另一个杯子;

使得一个杯子为满或者另一个杯子为空,求最少的操作次数使得B杯中的水为目标值。

分析:搜索。韩信走马分油。

设状态(a,b)为两倍的水容量,则最多1000000个状态,bfs求最短路(操作数最少)。

说明:很多年前写的代码,优化了一下(⊙_⊙)。

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>

using namespace std;

/*操作编号:
 *fill A    --------0
 *fill B    --------1
 *empty A   --------2
 *empty B   --------3
 *pour A B  --------4
 *pour B A  --------5
 */

int Ca,Cb,N;
int used[1001][1001]; /*  标记判重 */
typedef struct queue
{
	int a,b,p,o;
};
queue Q[1000001];

void output(int i)
{
	if (i < 0) return;
	else {
		output(Q[i].p);
		switch(Q[i].o) {
			case 0: cout << "fill A\n";   break;
			case 1: cout << "fill B\n";   break;
			case 2: cout << "empty A\n";  break;
			case 3: cout << "empty B\n";  break;
			case 4: cout << "pour A B\n"; break;
			case 5: cout << "pour B A\n"; break;
		}
	}
}

void search(int Ca , int Cb , int T)
{
	memset(used , 0, sizeof(used));
	used[0][0] = 1;
	Q[0].a = Q[0].b = 0;Q[0].p = Q[0].o = -1;
	int move = 0,save = 1;
	while (move < save) {
		queue Now = Q[move ++];
		for (int i = 0 ; i < 6 ; ++ i) {
			queue New = Now;
				  New.o = i; New.p = move-1;
			switch(i) {
				case 0: if (Now.a != Ca && Now.b != Cb)
							New.a = Ca;
						break;
				case 1: if (Now.a != Ca && Now.b != Cb)
							New.b = Cb;
						break;
				case 2: if (Now.a && Now.b)
							New.a = 0;
						break;
				case 3: if (Now.a && Now.b)
							New.b = 0;
						break;
				case 4: if (Now.b != Cb)
							if (Now.b + Now.a <= Cb) {
								New.b = Now.a + Now.b;
								New.a = 0;
							}else {
								New.b = Cb;
								New.a = Now.a - Cb + Now.b;
							}
						break;
				case 5: if (Now.a != Ca)
							if (Now.a + Now.b <= Ca) {
								New.a = Now.b + Now.a;
								New.b = 0;
							}else {
								New.a = Ca;
								New.b = Now.b - Ca + Now.a;
							}
						break;
			}
			if (!used[New.a][New.b]) {
				used[New.a][New.b] = 1;
				Q[save ++] = New;
				if (New.b == T) {
					output(save-1);
					cout << "success\n";
					return;
				}
			}
		}
	}
}

int main()
{
	while (cin >> Ca >> Cb >> N)
		search(Ca , Cb , N);
	return 0;
}
时间: 2025-01-02 15:07:19

UVa 571 - Jugs的相关文章

UVA - 571 - Jugs (数论 - 经典倒水问题)

题目传送:UVA - 571 思路:A为空时就加满,不空就倒给B,B满了后就全倒掉,直到B的容量为n(参考) AC代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <vector>

UVA 571 Jugs ADD18 小白书10 数学Part1 专题

只能往一个方向倒,如c1=3,c2=5,a b从0 0->0 5->3 2->0 2->2 0->2 5->3 4->0 4->3 1->0 1->1 5->3 3->0 3->0 0,又回到了0 0,而且倒着推回去正好是c1一直往c2倒,因为0*c2%c1->1*c2%c1->...->c1*c2%c1==0 1 #include <iostream> 2 #include<cstdio&g

uva 571 素数的性质

给定 两个杯子,容量分别分Ca,Cb, 要我们用这两个瓶子倒来倒去,得到某个瓶子里装有N的水 而且给的数据保证  Cb > N,且Ca,Cb互质 那么我们肯定可以在容量为Cb的杯子里得到N的水 Ca与Cb的最小公倍数是Ca*Cb 我们设ri <Cb 所以ri * Ca % Cb != 0,   而且得到的余数各不相同 因为如果有两个余数相同,我们不妨设 ri * Ca % Cb = rj * Ca % Cb    (rj>ri) 那么  那么 Ca*(rj-ri) %Cb =0  与  

UVA题目分类

题目 Volume 0. Getting Started 开始10055 - Hashmat the Brave Warrior 10071 - Back to High School Physics 10300 - Ecological Premium 458 - The Decoder 494 - Kindergarten Counting Game 414 - Machined Surfaces 490 - Rotating Sentences 445 - Marvelous Mazes

uva 10603 Fill (BFS)

uva 10603 Fill There are three jugs with a volume of a, b and c liters. (a, b, and c are positive integers not greater than 200). The first and the second jug are initially empty, while the third is completely filled with water. It is allowed to pour

UVA FILL(BFS + 优先队列)

Problem D FILL There are three jugs with a volume of a, b and c liters. (a, b, and c are positive integers not greater than 200). The first and the second jug are initially empty, while the third is completely filled with water. It is allowed to pour

UVA 562 Dividing coins --01背包的变形

01背包的变形. 先算出硬币面值的总和,然后此题变成求背包容量为V=sum/2时,能装的最多的硬币,然后将剩余的面值和它相减取一个绝对值就是最小的差值. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 50007 int c[102],d

UVA 10341 Solve It

Problem F Solve It Input: standard input Output: standard output Time Limit: 1 second Memory Limit: 32 MB Solve the equation: p*e-x + q*sin(x) + r*cos(x) + s*tan(x) + t*x2 + u = 0 where 0 <= x <= 1. Input Input consists of multiple test cases and te

UVA 11014 - Make a Crystal(容斥原理)

UVA 11014 - Make a Crystal 题目链接 题意:给定一个NxNxN的正方体,求出最多能选几个整数点.使得随意两点PQ不会使PQO共线. 思路:利用容斥原理,设f(k)为点(x, y, z)三点都为k的倍数的点的个数(要扣掉一个原点O).那么全部点就是f(1),之后要去除掉共线的,就是扣掉f(2), f(3), f(5)..f(n).n为素数.由于这些素数中包括了合数的情况,而且这些点必定与f(1)除去这些点以外的点共线,所以扣掉.可是扣掉后会扣掉一些反复的.比方f(6)在f