【隐式图搜索遍历学习】倒牛奶

【隐式图搜索遍历学习】倒牛奶_第1张图片



DFS:


#include
#include
#include
#include
using namespace std;

long ans[50], p = -1;
long a, b, c;                //各桶上限 
bool found[50][50][50];      //搜索记录 

bool isln(int C)             //判断是否有重复记录 
{
	bool in = false;
	for(int i = 0; i <= p; i++) {
		if(ans[i] == C) {
			in = true;
			break;
		}
	}
	return in;
}

void dfs(int A, int B, int C)
{
	if( found[A][B][C] ) return;   //当前状态以被搜索
	found[A][B][C] = true;
	if(A == 0 && !isln(C)) {       // A 桶中的牛奶为 0 && C桶中的数量不重复 
	      ans[++p] = C;             	
	} 
	//A->B 
	if(A <= b - B)  dfs(0, A + B, C); //若A桶中的牛奶数量少于b现在未填的容量,便将A中所有牛奶倒入B中
	else  dfs(A - (b - B), b, C);     //B中剩余容量比A少,则把B桶填满,A中剩余奶量是 A - (b - B)
	//A->C
	if(A <= c - C)  dfs(0, B, C + A); //若A桶中牛奶的数量少于C桶未满的容量, 便把A中的所有牛奶倒入C中
	else  dfs(A - (c - C), B, c);     //C中剩余容量比A少,便把C桶填满, A中剩余数量为 A - (c - C)
	//B->A
	if(B <= a - A)  dfs(A + B, 0, C);
	else  dfs(a, B - (a - A), C);
	//B->C
	if(B <= c - C)  dfs(A, 0, C + B);
	else  dfs(A, B - (a - A), c);
	//C->A
	if(C <= a - A)  dfs(A + C, B, 0);
	else  dfs(a, B, C - (a - A));
	//C->B
	if(C <= b - B)  dfs(A, B + C, 0);
	else dfs(A, b, C - (b - B)); 
	
	return;
}

int main()
{
	memset(ans, 0, sizeof(ans));
	memset(found, 0, sizeof(found));
	cin >> a >> b >> c;
	dfs(0, 0, c);
	sort(ans, ans + p + 1);
	for(int i = 0; i <= p; i++) {
		cout << ans[i] << " ";
	} 
	return 0;
} 


BFS:


#include
#include
#include
using namespace std;

struct milk{
	int a, b, c;
} ;

queue q;
priority_queue, greater > qq;
int a, b, c;
bool vis[21][21] = { false };

void bfs()
{
	milk t, tmp;
	t.a = 0;
	t.b = 0;
	t.c = c;
	q.push(t);
	vis[0][0] = 1;
	qq.push(c);
	
	while( !q.empty() ) {
		t = q.front();
		q.pop();
		tmp = t;
		if(t.a != 0) {                           	  //若a容量中的牛奶不空
			if(tmp.b != b) {                       	 //若b容量中的牛奶没满 
				if(tmp.a > b - tmp.b){               	//若a中的牛奶量大于b中剩余容量 
					tmp.a = tmp.a - (b - tmp.b);      //a中减少 temo.a - (b - tmp.b) 
					tmp.b = b;                          //此时的temo.b被填满,容量为b 
				} 
				else {                               //若a中奶量少于b中剩余容量 
					tmp.b += tmp.a;                //a中的牛奶全都倒入b中 
					tmp.a = 0;                      //a中剩余奶量为0 
				}
				if( !vis[tmp.a][tmp.b] ) {         //若当前状态没有被访问到 
					q.push(tmp);                    //将当前状态压入队列中 
					vis[tmp.a][tmp.b] = 1;         //标记当前状态已经被访问 
					if(tmp.a == 0) {                //如果a中的奶量为0 
						qq.push(tmp.c);             //则将现在c中的奶量压入到优先级队列中 
					}
				}
				tmp = t;                              //重新刷新tmp的值,模拟下一状态 
				if(tmp.c != c) {                      //若c中奶量未满 
					if(tmp.a > c - tmp.c) {          //若a的奶量大于c中剩余容量 
						tmp.a = tmp.a - (c - tmp.c);//a的奶量减少c - tmp.c 
						tmp.c = c;                    //把tmp.c的容器填满 
					}
					else {                             //若a中奶量少于b中剩余容量 
						tmp.c += tmp.a;              //将tmp.a中的牛奶全部倒入tmp.c中 
						tmp.a = 0;                    //tmp.a中的奶量为0 
					}
					if( !vis[tmp.a][tmp.b] ) {       //若当前状态没有访问过 
						q.push(tmp);                  //把当前状态压入到队列中 
						vis[tmp.a][tmp.b] = 1;       //标记状态已经访问过 
						if(tmp.a == 0) {              //若a中奶量为0 
							qq.push(tmp.c);           //便把此时的c奶量压入到优先级队列中 
						}
					} 
				} 
			}
		}
		tmp = t;
		if(tmp.b != 0) {                                 //若b中牛奶不空
			if(tmp.a != a) {                             //a中容量不空 
				if(tmp.b > a - tmp.a) {                 //b中奶量多余a中剩余容量 
					tmp.b = tmp.b - (a - tmp.a);       //b->a b中剩余容量为tmp.b - (a - tmp.a) 
					tmp.a = a;                           //tmp.a被装满 
				}
				else {                                    //b中奶量少于a中剩余容量                        
					tmp.a += tmp.b;                      //tmp.a的奶量为tmp.a + tmp.b 
					tmp.b = 0;                          //b中奶量为空 
				}
				if( !vis[tmp.a][tmp.b] ) {              //判断当前状态是否被访问 
					q.push(tmp);                         //把当前状态压入到队列中 
					vis[tmp.a][tmp.b] = 1;              //标记当前状态已经被访问过 
					if(tmp.a == 0) {                     //若a中的奶量为0,则将c的值压入到优先级队列中 
						qq.push(tmp.c);                  //把c的容量压入到优先级队列中 
					}
				}
			}
			if(tmp.c != c) {                             //若tmp.c的容量未满 
				if(tmp.b > c - tmp.c) {                 //b中奶量大于c中的剩余奶量 
					tmp.b = tmp.b - (c - tmp.c);       
					tmp.c = c; 
				}
				else {
					tmp.c += tmp.b;
					tmp.b = 0;
				}
				if( !vis[tmp.a][tmp.b] ) {
					q.push(tmp);
					vis[tmp.a][tmp.b] = 1;
					if(tmp.a == 0) {
						qq.push(tmp.c);
					}
				}
			} 
		}	
		tmp = t;
		if(tmp.c != 0) {
			if(tmp.a != a) {
				if(tmp.c > a - tmp.a) {
					tmp.c = tmp.c - (a - tmp.a);
					tmp.a = a;
				} 
				else {
					tmp.a += tmp.c;
					tmp.c = 0;
				}
				if( !vis[tmp.a][tmp.b] ) {
					q.push(tmp);
					vis[tmp.a][tmp.b] = 1;
					if(tmp.a == 0) {
						qq.push(tmp.c);
					}
				}
			}
			tmp = t;
			if(tmp.b != b) {
				if(tmp.c > b - tmp.b) {
					tmp.c = tmp.c - (b - tmp.b);
					tmp.b = b;
				}
				else {
					tmp.b += tmp.c;
					tmp.c = 0;
				}
				if( !vis[tmp.a][tmp.b] ) {
					q.push(tmp);
					vis[tmp.a][tmp.b] = 1;
					if(tmp.a == 0) {
						qq.push(tmp.c);
					}
				}
			}
		}
	} 
	while( !qq.empty() ) {
			cout << qq.top() << " ";
			qq.pop();
	}
}

int main()
{
	cin >> a >> b >> c;
	bfs(); 
	return 0;
}

你可能感兴趣的:(算法设计与学习)