codevs1226倒水问题(Bfs)

/*
首先建立模型 可以看成是三个水杯 第三个无穷大 (这里看成是201足够了)
最少步数 想到Bfs
维护队列里的状态:要有个步数  还要有v :此时刻三个杯子有多少水
然后倒水:因为没有刻度 所以有两种情况:要么出水的为空 要么接水的满了
然后每次取队首时判断有没有某一个杯子装的水恰好为答案
注意判重时可以弄一个f [a][b] 表示第一个杯子有a升水 第二个杯子有b升水的状态存在了没
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int x,y,z,f[101][101],c[4];
struct node
{
    int v[4];//此状态每个杯子的水有多少
    int step;//步数
};
queue<node>q;
int main()
{
    cin>>x>>y>>z;
    c[1]=x;c[2]=y;c[3]=201;//记号最大容量
    node be;
    be.step=0;
    be.v[1]=0;be.v[2]=0;
    be.v[3]=201;
    q.push(be);//出状态 前两个杯子空 第三个大杯子满
    while(!q.empty())
      {
          node tmp=q.front();
          q.pop();
          if(tmp.v[1]==z||tmp.v[2]==z)//判断符合条件了没有
            {
                cout<<tmp.step;
                return 0;
          }
          int i,j;
          for(i=1;i<=3;i++)// 枚举出水的杯子和接水的
            for(j=1;j<=3;j++)
              if(!tmp.v[i]||tmp.v[j]==c[j])continue;//如果出水的空了 或者接水的满了 跳过
              else
                {
                    int minn=min(tmp.v[i]+tmp.v[j],c[j])-tmp.v[j];//计算到多少水
                    node x=tmp;
                    x.v[i]-=minn;//倒水
                    x.v[j]+=minn;//节水
                    x.step=tmp.step+1;
                    if(f[x.v[1]][x.v[2]]==0)//判断此状态存在了没
                      {
                          f[x.v[1]][x.v[2]]=1;
                          q.push(x);
                  }
              }
      }
    cout<<"impossible";
    return 0;
}
时间: 2024-11-05 18:46:28

codevs1226倒水问题(Bfs)的相关文章

uva 10603 Fill(倒水问题 BFS)

貌似uva崩了,现在进不去,所以这道题还判断正确与否,其实无所谓了,我这是看的网上的代码,写的基本上一样,唉,没办法,不会做,又看了网上的题解,认真写理解吧还是... 构造了一个结构体,water数组用来保存三个杯子的状态,sum用来保存当前的倒水量,visit数组用来保存状态,以 防他们重复访问,三个杯子只需要两个杯子来判断,第三个已经确定,所以开一个二维数组就可以了...然后用 reach数组来存储所有的倒水量,下标是目标水量,值是一共的倒水量... 只需要一次BFS最多有200*200种状

搜索专题总结

搜索专题总结 第七章的例题做得差不多了,还有一道枚举二叉树和一道比较难的搜方块的没过,另外有一道火柴的用IDA*水过,并没有过大数据,由于这道可以用dancing links过,所以留着dancing links一坑.接下来总结下这章的收获,首先最重要的当然是不需要判重的高效率的IDA*以及估价函数的设计技巧:然后是bfs+hash写得更熟练了,如果hash需要erase那么就只能用指针版的,但是效率会很慢,否则就用数组版的. 做搜索题的几个要点: 1,估算最坏复杂度. 2,寻找合适的剪枝策略,

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 

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

HDOJ1495(倒水BFS)

#include"cstdio" #include"cstring" #include"queue" #include"algorithm" using namespace std; const int MAXN=105; struct node{ int s,n,m,step; node(int cs,int cn,int cm,int cstep):s(cs),n(cn),m(cm),step(cstep){} node(

Fill (Uva 10603 bfs 倒水问题)

题意:三个杯子容量分别为a,b,c,现在c是满的,a和b是空的,两个杯子 i 向 j 倒水,要么 i 倒完了 j 还没满,要么 j 满了 i 还有剩余,问达到某个杯子水量为d时总共倒得最小水量是多少?如果不能达到d,找一个小于d并且离d最近的一个解. 思路:倒水问题,但题目要求的是总的到水量,所以在bfs时到达过的状态还要检查更新,可能当前我确实到达d了用了sum水量,但可能后面还有比sum更小的解.网上有很多代码都是错误的,很多就是错在这里. 代码: #include <iostream>

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

题意  将体积为s的可乐  利用容积分别为n和m的两个杯子平均分为两份  至少需要倒多少次可乐 可以把容器s,n,m中装的可乐量看成一种状态 容器都是没有刻度的  所以每次倒可乐要么把自己倒完 要么把对方倒满 每种状态可以通过一次倒水到达哪些状态  于是可以通过bfs判断到达每种状态需要倒多少次 3个容器中有一个装的可乐为s/2的状态就是答案了  s是奇数时明显不可能平分的  可以直接忽略 #include <cstdio> #include <cstring> using nam