poj 3414 dfs 广度优先搜索

2024-05-15 05:38
文章标签 搜索 poj dfs 优先 广度 3414

本文主要是介绍poj 3414 dfs 广度优先搜索,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题意:

给定两个杯子的容量a,b和目标水量c 。

有六种操作:

1、倒满a杯子。

  2、倒满b杯子。

3、将a杯子的水全部倒出。 

4、将b杯子的水全部倒出。  

5、将a杯子的水倒到b杯子,直到a杯子倒尽或b杯子倒满。

6、将b杯子的水倒到a杯子,直到b杯子倒尽活a杯子倒满。

求:最少进行多少次操作使a或b任意一杯子的水量恰好等于目标水量c,并输出倒水的过程。

题目链接:http://poj.org/problem?id=3414

求解思路:6入口的BFS,记录每一次操作的前一次操作,当恰好找到目标状态的时候,从末尾找到初始状态输出。

#include<stdio.h>
#include<cstring>
#include<iostream>
#include<cstring>
using namespace std;
struct State
{int post;int a,b;int step;char d[10];
}state[10010];
int haha[10010];
int A,B,C;
bool visit[105][105];//标记该状态时否被访问过
int BFS()
{int head=0,tail=0;visit[0][0]=true;state[tail].a=0;state[tail].b=0;state[tail].step=0;state[tail].post=-2;tail++;while(1){State x=state[head];//cout<<state[head].a<<"*"<<state[head].b<<endl;if(head==tail){return -1;//队列为空,找不到.}if(x.a==C||x.b==C){return head;}if(!visit[A][x.b])// fill A;{visit[A][x.b]=true;state[tail].b=x.b;//这地方不要忘了记录,wa了好久state[tail].a=A;state[tail].post=head;strcpy(state[tail].d,"FILL(1)");state[tail++].step=x.step+1;}if(!visit[x.a][B]) //fill B{visit[x.a][B]=true;state[tail].a=x.a;state[tail].b=B;state[tail].post=head;strcpy(state[tail].d,"FILL(2)");state[tail++].step=x.step+1;}if(x.a+x.b<=B)    //pour(a,b){if(!visit[0][x.a+x.b]){visit[0][x.a+x.b]=true;state[tail].b=x.a+x.b;state[tail].a=0;state[tail].post=head;strcpy(state[tail].d,"POUR(1,2)");state[tail++].step=x.step+1;}}else{if(!visit[x.a-(B-x.b)][B]){visit[x.a-(B-x.b)][B]=true;state[tail].a=x.a-(B-x.b);state[tail].b=B;state[tail].post=head;strcpy(state[tail].d,"POUR(1,2)");state[tail++].step=x.step+1;}}if(x.b+x.a<=A)   //pour(b,a);{if(!visit[x.a+x.b][0]){visit[x.a+x.b][0]=true;state[tail].a=x.a+x.b;state[tail].step=x.step+1;state[tail].post=head;strcpy(state[tail].d,"POUR(2,1)");state[tail++].b=0;}}else{if(!visit[A][x.b-(A-x.a)]){visit[A][x.b-(A-x.a)]=true;state[tail].b=x.b-(A-x.a);state[tail].a=A;state[tail].post=head;strcpy(state[tail].d,"POUR(2,1)");state[tail++].step=x.step+1;}}if(!visit[0][x.b]) //drop A{visit[0][x.b]=true;state[tail].a=0;state[tail].b=x.b;state[tail].post=head;strcpy(state[tail].d,"DROP(1)");state[tail++].step=x.step+1;}if(!visit[x.a][0]) //drop B{visit[x.a][0]=true;state[tail].b=0;state[tail].a=x.a;state[tail].post=head;strcpy(state[tail].d,"DROP(2)");state[tail++].step=x.step+1;}head++;}
}
int main()
{while(scanf("%d%d%d",&A,&B,&C)!=EOF){memset(visit,false,sizeof(visit));int t=BFS();if(t==-1)printf("impossible\n");else{int i=0;while(state[t].post!=-2){haha[i]=t;i++;t=state[t].post;}cout<<i<<endl;for(int j=i-1;j>=0;j--){cout<<state[haha[j]].d<<endl;}}}return 0;


这篇关于poj 3414 dfs 广度优先搜索的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/990952

相关文章

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

hdu1240、hdu1253(三维搜索题)

1、从后往前输入,(x,y,z); 2、从下往上输入,(y , z, x); 3、从左往右输入,(z,x,y); hdu1240代码如下: #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#inc

hdu1180(广搜+优先队列)

此题要求最少到达目标点T的最短时间,所以我选择了广度优先搜索,并且要用到优先队列。 另外此题注意点较多,比如说可以在某个点停留,我wa了好多两次,就是因为忽略了这一点,然后参考了大神的思想,然后经过反复修改才AC的 这是我的代码 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s

poj 1511 Invitation Cards(spfa最短路)

题意是给你点与点之间的距离,求来回到点1的最短路中的边权和。 因为边很大,不能用原来的dijkstra什么的,所以用spfa来做。并且注意要用long long int 来存储。 稍微改了一下学长的模板。 stack stl 实现代码: #include<stdio.h>#include<stack>using namespace std;const int M

poj 3259 uva 558 Wormholes(bellman最短路负权回路判断)

poj 3259: 题意:John的农场里n块地,m条路连接两块地,w个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。 任务是求你会不会在从某块地出发后又回来,看到了离开之前的自己。 判断树中是否存在负权回路就ok了。 bellman代码: #include<stdio.h>const int MaxN = 501;//农场数const int

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

poj 1287 Networking(prim or kruscal最小生成树)

题意给你点与点间距离,求最小生成树。 注意点是,两点之间可能有不同的路,输入的时候选择最小的,和之前有道最短路WA的题目类似。 prim代码: #include<stdio.h>const int MaxN = 51;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int P;int prim(){bool vis[MaxN];

poj 2349 Arctic Network uva 10369(prim or kruscal最小生成树)

题目很麻烦,因为不熟悉最小生成树的算法调试了好久。 感觉网上的题目解释都没说得很清楚,不适合新手。自己写一个。 题意:给你点的坐标,然后两点间可以有两种方式来通信:第一种是卫星通信,第二种是无线电通信。 卫星通信:任何两个有卫星频道的点间都可以直接建立连接,与点间的距离无关; 无线电通信:两个点之间的距离不能超过D,无线电收发器的功率越大,D越大,越昂贵。 计算无线电收发器D