• uva10603-倒水问题-暴力枚举-隐式图搜索


    题意:

    给你三个杯子,a,b,c,没有刻度,刚开始c杯是满的,倒水的要求,要么倒出水的杯子倒空,要么倒入杯子倒满.

    结果:

    要求某个杯子内有d水量,并且倒出的水量最少,如果倒不出d水量,那么倒出d1(d1<d)水量,并且倒出的水量最少

    解题思路:

    总的水量为c,只要知道前俩个杯子的水量,那么第三个杯子的水量就确定了,所以,状态数最大只有a * b种,所以一个二维数组标记状态就够.

    要求倒出的水量最少,那么使用优先队列,按照倒出的水量最少开始搜索.

    初始化结点为(0,0,c),由这个结点开始往外扩展,此时倒出的水量为0,结果d为0,注意代码内有个特判,如果d >= c,那么最大的d就是c,倒出的水量为0

    #include <iostream>
    #include <stdio.h>
    #include <memory.h>
    #include <queue>
    
    using namespace std;
    const int NN = 201;
    int a[3];
    int d;
    int maxD = -1;
    int maxNum = 0;
    //记录c1,c2,已知c1,c2,c3就可以确定
    int vis[NN][NN];
    class State
    {
    	public:
    		int a[3];
    		int waterNum;
    		State()
    				: waterNum(0)
    		{
    			a[0] = 0;
    			a[1] = 0;
    			a[2] = 0;
    		}
    		State(int d1, int d2, int d3, int w)
    				: waterNum(w)
    		{
    			a[0] = d1;
    			a[1] = d2;
    			a[2] = d3;
    		}
    		bool operator ()(State& a, State& b)
    		{
    			return a.waterNum > b.waterNum;
    		}
    };
    priority_queue<State, vector<State>, State> q;
    void bfs()
    {
    	while (!q.empty())
    	{
    		State s = q.top();
    		q.pop();
    		for(int i = 0; i < 3; i++)
    			for(int j = 0; j < 3; j++)
    			{
    				if(i == j || s.a[i] == 0)
    					continue;
    				//把水从i导入j中
    				//要么i倒空,要么j倒满
    				int dj = a[j] - s.a[j];
    				if(dj == 0)
    					//j是满的,不能倒
    					continue;
    				//i杯内的水量
    				int di = s.a[i];
    				//倒出的水量
    				State ss(s.a[0], s.a[1], s.a[2], s.waterNum);
    				if(dj > di)
    				{
    					//i杯倒空
    					ss.waterNum = ss.waterNum + di;
    					ss.a[i] = 0;
    					ss.a[j] = ss.a[j] + di;
    				}
    				else
    				{
    					//j杯倒满
    					ss.waterNum = ss.waterNum + dj;
    					ss.a[i] = di - dj;
    					ss.a[j] = ss.a[j] + dj;
    				}
    				if(vis[ss.a[0]][ss.a[1]])
    					continue;
    				//判断当前状态
    				if(ss.a[i] <= d && ss.a[i] > maxD)
    				{
    					maxD = ss.a[i];
    					maxNum = ss.waterNum;
    				}
    				if(ss.a[j] <= d && ss.a[j] > maxD)
    				{
    					maxD = ss.a[j];
    					maxNum = ss.waterNum;
    				}
    				if(maxD == d)
    					return;
    				q.push(ss);
    				vis[ss.a[0]][ss.a[1]] = 1;
    			}
    	}
    }
    void clear()
    {
    	while (!q.empty())
    		q.pop();
    	memset(vis, 0, sizeof(vis));
    	maxNum = 0;
    	maxD = 0;
    }
    int main()
    {
    	int num;
    	cin >> num;
    	while (num--)
    	{
    		clear();
    		cin >> a[0] >> a[1] >> a[2] >> d;
    		if(d >= a[2])
    		{
    			cout << 0 << " " << a[2] << endl;
    			continue;
    		}
    		State state(0, 0, a[2], 0);
    		q.push(state);
    		vis[0][0] = 1;
    		bfs();
    		if(maxD == 0)
    			cout << 0 << " " << 0 << endl;
    		else
    			cout << maxNum << " " << maxD << endl;
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    vagrant 入门3
    vagrant 入门4
    vagrant 入门2
    Map、Debug追踪
    Comparator比较器 、Comparable接口
    File类
    Lambda表达式、函数式编程思想概述
    异常--异常体系、异常的处理、异常的捕获、finally语句块和自定义异常
    List集合、Set集合、Collection集合工具类
    数据结构---栈、队列、数组、链表和红黑树
  • 原文地址:https://www.cnblogs.com/shuiyonglewodezzzzz/p/9310646.html
Copyright © 2020-2023  润新知