poj3414有向图的搜索BFS+路径记录
2015-06-26 23:48
621 查看
代码偏长只是大体思路
//这道题不能深度回溯的方法,因为倒水的状态是有向图
//那么只能用宽度搜索的方法
//同时我们应该记录路径当找到最优解就退出
//388K 0MS
#include <iostream>
#include <queue>
using namespace std;
#define MAX_N 103
#define For(i,a,b) for(int i=a;i<=b;++i)
#define Rep(i,a,b) for(int i=a;i>=b;--i)
enum oper
{
FILLA,FILLB,DROPA,DROPB,POURA,POURB
};
static struct state
{
int a,b;
int patha,pathb;
int t;
oper op;
}States[110][110];
static int vis[110][110];
static int A,B,C;
static void findpath(int ea,int eb,int t)
{
int eea,eeb;
oper path[1000];
int cnt = 0;
Rep(i,t,1)
{
path[cnt++] = States[ea][eb].op;
eea = ea;eeb = eb;
ea = States[eea][eeb].patha;eb=States[eea][eeb].pathb;
}
Rep(i,cnt-1,0)
{
if (path[i]==FILLA)
printf("FILL(1)\n");
else if (path[i]==FILLB)
printf("FILL(2)\n");
else if (path[i]==DROPA)
printf("DROP(1)\n");
else if (path[i]==DROPB)
printf("DROP(2)\n");
else if (path[i]==POURA)
printf("POUR(1,2)\n");
else if(path[i]==POURB)
printf("POUR(2,1)\n");
}
}
static void BFS()
{
int finda,findb;
state s,s1;
queue<state>que;
s.a = 0;s.b = 0;s.t=0;
que.push(s);
int ans = -1;
while(!que.empty())
{
s = que.front();que.pop();
//判断是否已经找到结果
if (s.a==C||s.b==C)
{
ans = s.t;finda = s.a;findb = s.b;
break;
}
//对于A杯子有3种选择
if (s.a<A)//加满水
{
s1.a = A;s1.b = s.b;s1.t = s.t+1;
if(!vis[s1.a][s1.b]){
que.push(s1);
States[s1.a][s1.b].op = FILLA;
States[s1.a][s1.b].patha = s.a;
States[s1.a][s1.b].pathb = s.b;
vis[s1.a][s1.b] = 1;
}
}
if (s.a>0)
{
s1.a = 0;s1.b = s.b;s1.t = s.t+1;
if(!vis[s1.a][s1.b]){
que.push(s1);
States[s1.a][s1.b].op = DROPA;
States[s1.a][s1.b].patha = s.a;
States[s1.a][s1.b].pathb = s.b;
vis[s1.a][s1.b] = 1;
}
}
if (s.a>0&&s.b<B)
{
if (B-s.b<s.a)
{
s1.a = s.a - (B-s.b);s1.b = B;s1.t = s.t+1;
if(!vis[s1.a][s1.b]){
que.push(s1);
vis[s1.a][s1.b] = 1;
States[s1.a][s1.b].op = POURA;
States[s1.a][s1.b].patha = s.a;
States[s1.a][s1.b].pathb = s.b;
}
}
else
{
s1.a = 0;s1.b = s.b+s.a;s1.t = s.t+1;
if(!vis[s1.a][s1.b]){
que.push(s1);
vis[s1.a][s1.b] = 1;
States[s1.a][s1.b].op = POURA;
States[s1.a][s1.b].patha = s.a;
States[s1.a][s1.b].pathb = s.b;
}
}
}
//对于B杯子的水
if (s.b<B)//加满水
{
s1.a = s.a;s1.b = B;s1.t = s.t+1;s1.patha = s.a;s1.pathb = s.b;
if(!vis[s1.a][s1.b]){
que.push(s1);
vis[s1.a][s1.b] = 1;
States[s1.a][s1.b].op = FILLB;
States[s1.a][s1.b].patha = s.a;
States[s1.a][s1.b].pathb = s.b;
}
}
if (s.b>0)
{
s1.a = s.a;s1.b = 0;s1.t = s.t+1;s1.patha = s.a;s1.pathb = s.b;
if(!vis[s1.a][s1.b]){
que.push(s1);
vis[s1.a][s1.b] = 1;
States[s1.a][s1.b].op = DROPB;
States[s1.a][s1.b].patha = s.a;
States[s1.a][s1.b].pathb = s.b;
}
}
if (s.b>0&&s.a<A)
{
if (A-s.a<s.b)
{
s1.b = s.b - (A-s.a);s1.a = A;s1.t = s.t+1;s1.patha = s.a;s1.pathb = s.b;
if(!vis[s1.a][s1.b]){
que.push(s1);
vis[s1.a][s1.b] = 1;
States[s1.a][s1.b].op = POURB;
States[s1.a][s1.b].patha = s.a;
States[s1.a][s1.b].pathb = s.b;
}
}
else
{
s1.a = s.a+s.b;s1.b = 0;s1.t = s.t+1;s1.patha = s.a;s1.pathb = s.b;
if(!vis[s1.a][s1.b]){
que.push(s1);
vis[s1.a][s1.b] = 1;
States[s1.a][s1.b].op = POURB;
States[s1.a][s1.b].patha = s.a;
States[s1.a][s1.b].pathb = s.b;
}
}
}
}
s.a = s.b = 0;
if (ans==-1)
{
printf("impossible\n");
return;
}
printf("%d\n",ans);
findpath(finda,findb,ans);
}
int main()
{
scanf("%d %d %d",&A,&B,&C);
BFS();
return 0;
}
//这道题不能深度回溯的方法,因为倒水的状态是有向图
//那么只能用宽度搜索的方法
//同时我们应该记录路径当找到最优解就退出
//388K 0MS
#include <iostream>
#include <queue>
using namespace std;
#define MAX_N 103
#define For(i,a,b) for(int i=a;i<=b;++i)
#define Rep(i,a,b) for(int i=a;i>=b;--i)
enum oper
{
FILLA,FILLB,DROPA,DROPB,POURA,POURB
};
static struct state
{
int a,b;
int patha,pathb;
int t;
oper op;
}States[110][110];
static int vis[110][110];
static int A,B,C;
static void findpath(int ea,int eb,int t)
{
int eea,eeb;
oper path[1000];
int cnt = 0;
Rep(i,t,1)
{
path[cnt++] = States[ea][eb].op;
eea = ea;eeb = eb;
ea = States[eea][eeb].patha;eb=States[eea][eeb].pathb;
}
Rep(i,cnt-1,0)
{
if (path[i]==FILLA)
printf("FILL(1)\n");
else if (path[i]==FILLB)
printf("FILL(2)\n");
else if (path[i]==DROPA)
printf("DROP(1)\n");
else if (path[i]==DROPB)
printf("DROP(2)\n");
else if (path[i]==POURA)
printf("POUR(1,2)\n");
else if(path[i]==POURB)
printf("POUR(2,1)\n");
}
}
static void BFS()
{
int finda,findb;
state s,s1;
queue<state>que;
s.a = 0;s.b = 0;s.t=0;
que.push(s);
int ans = -1;
while(!que.empty())
{
s = que.front();que.pop();
//判断是否已经找到结果
if (s.a==C||s.b==C)
{
ans = s.t;finda = s.a;findb = s.b;
break;
}
//对于A杯子有3种选择
if (s.a<A)//加满水
{
s1.a = A;s1.b = s.b;s1.t = s.t+1;
if(!vis[s1.a][s1.b]){
que.push(s1);
States[s1.a][s1.b].op = FILLA;
States[s1.a][s1.b].patha = s.a;
States[s1.a][s1.b].pathb = s.b;
vis[s1.a][s1.b] = 1;
}
}
if (s.a>0)
{
s1.a = 0;s1.b = s.b;s1.t = s.t+1;
if(!vis[s1.a][s1.b]){
que.push(s1);
States[s1.a][s1.b].op = DROPA;
States[s1.a][s1.b].patha = s.a;
States[s1.a][s1.b].pathb = s.b;
vis[s1.a][s1.b] = 1;
}
}
if (s.a>0&&s.b<B)
{
if (B-s.b<s.a)
{
s1.a = s.a - (B-s.b);s1.b = B;s1.t = s.t+1;
if(!vis[s1.a][s1.b]){
que.push(s1);
vis[s1.a][s1.b] = 1;
States[s1.a][s1.b].op = POURA;
States[s1.a][s1.b].patha = s.a;
States[s1.a][s1.b].pathb = s.b;
}
}
else
{
s1.a = 0;s1.b = s.b+s.a;s1.t = s.t+1;
if(!vis[s1.a][s1.b]){
que.push(s1);
vis[s1.a][s1.b] = 1;
States[s1.a][s1.b].op = POURA;
States[s1.a][s1.b].patha = s.a;
States[s1.a][s1.b].pathb = s.b;
}
}
}
//对于B杯子的水
if (s.b<B)//加满水
{
s1.a = s.a;s1.b = B;s1.t = s.t+1;s1.patha = s.a;s1.pathb = s.b;
if(!vis[s1.a][s1.b]){
que.push(s1);
vis[s1.a][s1.b] = 1;
States[s1.a][s1.b].op = FILLB;
States[s1.a][s1.b].patha = s.a;
States[s1.a][s1.b].pathb = s.b;
}
}
if (s.b>0)
{
s1.a = s.a;s1.b = 0;s1.t = s.t+1;s1.patha = s.a;s1.pathb = s.b;
if(!vis[s1.a][s1.b]){
que.push(s1);
vis[s1.a][s1.b] = 1;
States[s1.a][s1.b].op = DROPB;
States[s1.a][s1.b].patha = s.a;
States[s1.a][s1.b].pathb = s.b;
}
}
if (s.b>0&&s.a<A)
{
if (A-s.a<s.b)
{
s1.b = s.b - (A-s.a);s1.a = A;s1.t = s.t+1;s1.patha = s.a;s1.pathb = s.b;
if(!vis[s1.a][s1.b]){
que.push(s1);
vis[s1.a][s1.b] = 1;
States[s1.a][s1.b].op = POURB;
States[s1.a][s1.b].patha = s.a;
States[s1.a][s1.b].pathb = s.b;
}
}
else
{
s1.a = s.a+s.b;s1.b = 0;s1.t = s.t+1;s1.patha = s.a;s1.pathb = s.b;
if(!vis[s1.a][s1.b]){
que.push(s1);
vis[s1.a][s1.b] = 1;
States[s1.a][s1.b].op = POURB;
States[s1.a][s1.b].patha = s.a;
States[s1.a][s1.b].pathb = s.b;
}
}
}
}
s.a = s.b = 0;
if (ans==-1)
{
printf("impossible\n");
return;
}
printf("%d\n",ans);
findpath(finda,findb,ans);
}
int main()
{
scanf("%d %d %d",&A,&B,&C);
BFS();
return 0;
}
相关文章推荐
- 搜狗百度360市值齐跌:搜索引擎们陷入集体焦虑?
- 本人即将筹备败家日志,敬请期待!
- IE:使用搜索助手
- C++深度优先搜索的实现方法
- 基于文本的搜索
- 使用Sphinx对索引进行搜索
- asp 多关键词搜索的简单实现方法
- C#使用foreach语句搜索数组元素的方法
- Javascript SHA-1:Secure Hash Algorithm
- JavaScript中数组的排序、乱序和搜索实现代码
- C#编程实现Excel文档中搜索文本内容的方法及思路
- sqlserver中在指定数据库的所有表的所有列中搜索给定的值
- 可以用来搜索当前页面内容的js代码
- 全文搜索和替换
- javascript搜索自动提示功能的实现第1/3页
- mysql 模糊搜索的方法介绍
- 基于ASP.NET的lucene.net全文搜索实现步骤
- 做个自己站内搜索引擎
- PHP查找与搜索数组元素方法总结
- JavaScript搜索字符串并将搜索结果返回到字符串的方法