首页 > 代码库 > 三个水杯吧!
三个水杯吧!
BFS,隐式图的遍历。
/** **author :Skylon ** ╭︿︿︿╮ {/ A C /} ( (OO) ) ︶︶︶ ** ** **NYOJ_21题** ** 2014 年 7月 18日** **/ #include <cmath> #include <queue> #include <stack> #include <vector> #include <cstdio> #include <string> #include <cctype> #include <climits> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; struct CUP//用一个结构体来表示三个水杯的状态,三个水杯分别标记为0、1、2,step为所需要操作的次数。 { int a[3]; int step; }cup,s,e;//s为起始状态,e为目标状态 bool flag[110][110][110];//用来标记水杯的状态,虽然是三维的,但是不要在意这些细节,作用就是标记而已,因为有三个杯子,所以是三维的。如果题目是四个水杯... int dir[6][2]= { 0,1, //把0杯中的水倒入1杯 0,2, //把0杯中的水倒入2杯 1,0, //把1杯中的水倒入0杯 1,2, //把1杯中的水倒入2杯 2,0, //把2杯中的水倒入0杯 2,1 //把2杯中的水倒入1杯 };//这是搜索的方向,一共有6个。其实本没有方向,只是将倒水的过程抽象化了。三个水杯,每次只能选择其中的两个水杯来进行倒水操作,当然就有6种倒水方式。在给三个水杯标记为0、1、2这三个号之后,就用0,1表示把编号为0的水杯中的水倒入编号为1的水杯中。 int del(CUP &p,int x,int y)//用来模拟倒水过程,在三个水杯的p状态下,将这个状态下编号为x的水杯中的水到入编号为y的水杯中。注意<span style="font-family: Arial, Helvetica, sans-serif;">CUP &p</span>{ if (p.a[x]==0||p.a[y]==s.a[y])//因为是将x倒入y中。所以,如果x杯中没有水或是y杯中的水满了,就不能倒水了 return 0; else//把x被中的水倒入y杯中,只有两种情况 { if (p.a[x]+p.a[y]<=s.a[y])//x杯中的水能全部倒入y杯中 { p.a[y]+=p.a[x]; //注意 p.a[x]=0; //注意 } else//x杯中的水不能全部倒入y杯中 { p.a[x]-=(s.a[y]-p.a[y]); //注意 p.a[y]=s.a[y]; //注意 }//注意上面两个模拟过程中的顺序不能交换 if (flag[p.a[0]] [p.a[1]] [p.a[2]]==false)//标记状态,并返回。模拟倒水过程成功。 { flag[p.a[0]][p.a[1]][p.a[2]]=true; return 1; } } } int bfs()//广搜 { CUP cup;//定义初始节点,状态初始化 cup.a[0]=s.a[0];//开始的时候只有最大的水杯中装满水 cup.a[1]=cup.a[2]=cup.step=0;//其余的两个水杯中没有水,且初始操作数位01 queue<CUP>v; v.push(cup); flag[cup.a[0]][cup.a[1]][cup.a[2]]=true;//标记初始状态 while (!v.empty()) { CUP now=v.front(); v.pop(); if (now.a[0]==e.a[0]&&now.a[1]==e.a[1]&&now.a[2]==e.a[2])//当bfs到目标状态时就... return now.step; for (int i=0;i<6;i++)//向六个方向搜索 { CUP pre=now; if (del(pre,dir[i][0],dir[i][1])) { pre.step=now.step+1; v.push(pre); } } } return -1;//没有到达终点就-1咯 } int main() { int n; scanf("%d",&n); while (n--) { cin>>s.a[0]>>s.a[1]>>s.a[2]>>e.a[0]>>e.a[1]>>e.a[2];//读入起点和终点 memset(flag,0,sizeof(flag)); printf("%d\n",bfs()); } return 0; }
三个水杯吧!
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。