uva10603-倒水

此题为小白书暴力求解法隐式图搜索的训练参考

题目链接 http://acm.hust.edu.cn/vjudge/problem/19527

解题思路

因为要求最小倒水量,所以不能把重复的节点都去掉,要把倒水量比较小的节点也加进去。

可以建立一个water数组,water[x]表示达到x水量的最小倒水量。之后每次扩展节点或者

是加入较小节点,也要更新water数组。

要具体的话可以看代码。

代码

#include<stdio.h>
#include<string.h>
const int maxLen = 5e5;
typedef struct node {
    int cup[3];
    int water;
}Node;
Node Q[maxLen];
int waters[201];
bool ex[201][201][201];
int maxcup[3];
int target;
bool match(Node x)
{
    return ex[x.cup[0]][x.cup[1]][x.cup[2]];
}
bool Judge(Node x)
{
    if(x.water<waters[x.cup[0]]) { waters[x.cup[0]]=x.water;return true; }
    if(x.water<waters[x.cup[1]]) { waters[x.cup[1]]=x.water;return true; }
    if(x.water<waters[x.cup[2]]) { waters[x.cup[2]]=x.water;return true; }
    return false;
}
int Search(Node Start)
{
    bool yes=false;
    int front=-1, rear=-1;
    Q[++rear] = Start;
    ex[Start.cup[0]][Start.cup[1]][Start.cup[2]]=true;
    Judge(Start);
    while(front != rear) {
        Node temp = Q[++front];
        for(int i=0; i<3; i++)
            for(int j=0; j<3; j++) if(i!=j) {
                Node mid = temp;
                mid.cup[i]+=temp.cup[j]+temp.cup[i]<=maxcup[i]?temp.cup[j]:maxcup[i]-temp.cup[i];
                mid.cup[j]=temp.cup[j]+temp.cup[i]<=maxcup[i]?0:temp.cup[j]-maxcup[i]+temp.cup[i];
                mid.water+=temp.cup[j]+temp.cup[i]<=maxcup[i]?temp.cup[j]:maxcup[i]-temp.cup[i];
                if(!match(mid) || Judge(mid)) {
                    Q[++rear] = mid;
                    ex[mid.cup[0]][mid.cup[1]][mid.cup[2]]=true;
                }
            }
    }
    while(target>=0) {
        if(waters[target]!=1e9) return waters[target];
        target--;
    }
}
int main()
{
    int n;
    scanf("%d", &n);
    while(n--) {
        memset(ex, 0, sizeof(ex));
        for(int i=0; i<201; i++) waters[i]=1e9;
        scanf("%d%d%d%d", &maxcup[0], &maxcup[1], &maxcup[2], &target);
        if(target>200) target=200;
        Node start;
        start.cup[2] = maxcup[2]; start.cup[0] = start.cup[1] = 0; start.water = 0;
        int water = Search(start);
        printf("%d %d\n", water, target);
    }
    return 0;
}
时间: 2024-08-05 09:20:33

uva10603-倒水的相关文章

UVa10603 倒水 Fill-状态空间搜索

https://vjudge.net/problem/UVA-10603 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.

UVA10603 Fill

优秀的程序员一定是CV大师.能CV则CV的做法,可以省去许多编码和测试的时间.但是,如果出现小错误的话,找起来一样的费时. 问题链接:UVA10603 Fill. 题意简述:有三个壶,容量分别是a.b和c升,开始时候第1个和第2个壶是空的,第3个壶是满水的.可以把一个壶的水倒入另一个壶中,直到倒空或将另外一个壶倒满.输入a.b.c和d,计算最少的倒水量,使得其中一个壶里有d升水.如果不能倒出d升水的话,那么找一个最大的d'<d.输出倒水量和d,如果找不到的话输出倒水量和d'. 问题分析:将<a

UVa 10603 倒水问题

https://vjudge.net/problem/UVA-10603 题意:三个杯子,倒水问题.找出最少倒水量. 思路:路径寻找问题.不难,暴力枚举. 1 #include<iostream> 2 #include<queue> 3 #include<string> 4 #include<cstring> 5 using namespace std; 6 7 int a, b, c, d; 8 int vis[205][205]; //访问变量,因为只有

倒水问题

[题目描述] 有两个无刻度标志的水壶,分别可装x升和y升(x,y为整数且均不大于100)的水.设另有一水缸,可用来向水壶灌水或接从水壶中倒出的水,两水壶间,水也可以相互倾倒.已知x升壶为空壶,y升壶为空壶.问如何通过倒水或灌水操作,用最少步数能在x或y升的壶中量出z(z ≤ 100)升的水来. [输入描述] 一行,三个数据,分别表示x,y和z. [输出描述] 一行,输出最小步数,如果无法达到目标,则输出“impossible”. [样例输入] 3 22 1 [样例输出] 14

Pots BFS(著名倒水问题升级版)

Pots 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 

2017广东工业大学程序设计竞赛 E倒水(Water)

原题链接:http://www.gdutcode.sinaapp.com/problem.php?cid=1057&pid=4 Problem E: 倒水(Water) Description 一天,CC买了N个容量可以认为是无限大的瓶子,开始时每个瓶子里有1升水.接着~~CC发现瓶子实在太多了,于是他决定保留不超过K个瓶子.每次他选择两个当前含水量相同的瓶子,把一个瓶子的水全部倒进另一个里,然后把空瓶丢弃.(不能丢弃有水的瓶子) 显然在某些情况下CC无法达到目标,比如N=3,K=1.此时CC会

HDU 1495 非常可乐(BFS倒水问题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1495 题目大意:只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) .如果能将可乐平分则输出倒可乐的最少的次数,如果不能输出"NO". 解题思路:题意很坑看了半天,就是要有两个杯子里的可乐都为S/2,S为奇数肯

【CodeVS1226】倒水问题

题目描述 Description 有两个无刻度标志的水壶,分别可装 x 升和 y 升 ( x,y 为整数且均不大于 100 )的水.设另有一水 缸,可用来向水壶灌水或接从水壶中倒出的水, 两水壶间,水也可以相互倾倒.已知 x 升壶为空 壶, y 升壶为空壶.问如何通过倒水或灌水操作, 用最少步数能在x或y升的壶中量出 z ( z ≤ 100 )升的水 来. 输入描述 Input Description 一行,三个数据,分别表示 x,y 和 z; 输出描述 Output Description 一

BFS(倒水问题) HDU 1495 非常可乐

题目传送门 1 /* 2 BFS:倒水问题,当C是奇数时无解.一共有六种情况,只要条件符合就入队,我在当该状态vised时写了continue 3 结果找了半天才发现bug,泪流满面....(网上找份好看的题解都难啊) 4 */ 5 /************************************************ 6 Author :Running_Time 7 Created Time :2015-8-4 10:54:16 8 File Name :HDOJ_1495.cpp

1226 倒水问题

1226 倒水问题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 有两个无刻度标志的水壶,分别可装 x 升和 y 升 ( x,y 为整数且均不大于 100 )的水.设另有一水 缸,可用来向水壶灌水或接从水壶中倒出的水, 两水壶间,水也可以相互倾倒.已知 x 升壶为空 壶, y 升壶为空壶.问如何通过倒水或灌水操作, 用最少步数能在x或y升的壶中量出 z ( z ≤ 100 )升的水 来. 输入描述 Input Descript