已知有三个容量分别为1斤、7两和3两的并且是没有刻度的酒瓶,1斤的瓶子装满了酒,而7两和三两的瓶子为空。现要求将这些酒分出5两出来。
BFS:
#include<iostream>
#include<stdio.h>
#include<map>
#include<vector>
#include<queue>
#include<set>
#include<cstdlib>
#include<string.h>
#include<algorithm>
#include<cmath>
#define MAXN 1000010
#define EPS 1e-9
using namespace std;
struct node{
int a;//对应容量为一斤的瓶子里当前所装的酒量
int b;//对应容量为七两的瓶子里当前所装的酒量
int c;//对应容量为三两的瓶子里当前所装的酒量
int pre;//父节点id
int id;//节点id
string str;//记录该状态对应的操作
}state[1000010];
int vis[100][100][100];
int cnt;
int num;
int ids[1000];
/****************************************
BFS函数说明:枚举各种倒满方案,依次进行广搜
参数:v1,v2,v3依次为瓶子容量,a,b,c为所装酒量,x为要称出的酒量
********************************************/
int BFS(int v1,int v2,int v3,int a,int b,int c,int x)
{
int fg=-1;
num=0;
queue<node>q;
memset(vis,0,sizeof(vis));
node cur,nex;
cur.a=a;
cur.b=b;
cur.c=c;
cur.str="";
cur.pre=cur.id=0;
q.push(cur);
vis[a][b][c]=1;
cnt=0;
state[cnt]=cur;
while(!q.empty())
{
cur=q.front();
q.pop();
if(cur.a==x||cur.b==x||cur.c==x)//找到解
{
fg=1;
ids[++num]=cur.id;
continue;
//return cur.id;
}
else
{
//1斤倒满7两
if(cur.a!=0 && cur.b!=v2)
{
nex.str="a->b ";
if(cur.a+cur.b <= v2)
{
nex.a=0;
nex.b=cur.b+cur.a;
nex.c=cur.c;
if(!vis[nex.a][nex.b][nex.c])
{
nex.pre=cur.id;
cnt++;
nex.id=cnt;
state[cnt]=nex;
q.push(nex);
vis[nex.a][nex.b][nex.c]=1;
}
}
else
{
nex.a=cur.b+cur.a-v2;
nex.b=v2;
nex.c=cur.c;
if(!vis[nex.a][nex.b][nex.c])
{
nex.pre=cur.id;
cnt++;
nex.id=cnt;
state[cnt]=nex;
q.push(nex);
vis[nex.a][nex.b][nex.c]=1;
}
}
}
//7两倒满1斤
if(cur.a!=v1 && cur.b!=0)
{
nex.str="b->a ";
if(cur.a+cur.b <= v1)
{
nex.b=0;
nex.a=cur.b+cur.a;
nex.c=cur.c;
if(!vis[nex.a][nex.b][nex.c])
{
nex.pre=cur.id;
cnt++;
nex.id=cnt;
state[cnt]=nex;
q.push(nex);
vis[nex.a][nex.b][nex.c]=1;
}
}
else
{
nex.b=cur.b+cur.a-v1;
nex.a=v1;
nex.c=cur.c;
if(!vis[nex.a][nex.b][nex.c])
{
nex.pre=cur.id;
cnt++;
nex.id=cnt;
state[cnt]=nex;
q.push(nex);
vis[nex.a][nex.b][nex.c]=1;
}
}
}
//1斤倒满3两
if(cur.a!=0 && cur.c!=v3)
{
nex.str="a->c ";
if(cur.a+cur.c <= v3)
{
nex.a=0;
nex.c=cur.c+cur.a;
nex.b=cur.b;
if(!vis[nex.a][nex.b][nex.c])
{
nex.pre=cur.id;
cnt++;
nex.id=cnt;
state[cnt]=nex;
q.push(nex);
vis[nex.a][nex.b][nex.c]=1;
}
}
else
{
nex.a=cur.c+cur.a-v3;
nex.c=v3;
nex.b=cur.b;
if(!vis[nex.a][nex.b][nex.c])
{
nex.pre=cur.id;
cnt++;
nex.id=cnt;
state[cnt]=nex;
q.push(nex);
vis[nex.a][nex.b][nex.c]=1;
}
}
}
//3两倒满1斤
if(cur.a!=v1 && cur.c!=0)
{
nex.str="c->a ";
if(cur.a+cur.c <= v1)
{
nex.c=0;
nex.a=cur.c+cur.a;
nex.b=cur.b;
if(!vis[nex.a][nex.b][nex.c])
{
nex.pre=cur.id;
cnt++;
nex.id=cnt;
state[cnt]=nex;
q.push(nex);
vis[nex.a][nex.b][nex.c]=1;
}
}
else
{
nex.c=cur.c+cur.a-v1;
nex.a=v1;
nex.b=cur.b;
if(!vis[nex.a][nex.b][nex.c])
{
nex.pre=cur.id;
cnt++;
nex.id=cnt;
state[cnt]=nex;
q.push(nex);
vis[nex.a][nex.b][nex.c]=1;
}
}
}
//7两倒满3两
if(cur.b!=0 && cur.c!=v3)
{
nex.str="b->c ";
if(cur.b+cur.c <= v3)
{
nex.b=0;
nex.c=cur.c+cur.b;
nex.a=cur.a;
if(!vis[nex.a][nex.b][nex.c])
{
nex.pre=cur.id;
cnt++;
nex.id=cnt;
state[cnt]=nex;
q.push(nex);
vis[nex.a][nex.b][nex.c]=1;
}
}
else
{
nex.b=cur.c+cur.b-v3;
nex.c=v3;
nex.a=cur.a;
if(!vis[nex.a][nex.b][nex.c])
{
nex.pre=cur.id;
cnt++;
nex.id=cnt;
state[cnt]=nex;
q.push(nex);
vis[nex.a][nex.b][nex.c]=1;
}
}
}
//3两倒满7两
if(cur.c!=0 && cur.b!=v2)
{
nex.str="c->b ";
if(cur.b+cur.c <= v2)
{
nex.c=0;
nex.b=cur.c+cur.b;
nex.a=cur.a;
if(!vis[nex.a][nex.b][nex.c])
{
nex.pre=cur.id;
cnt++;
nex.id=cnt;
state[cnt]=nex;
q.push(nex);
vis[nex.a][nex.b][nex.c]=1;
}
}
else
{
nex.c=cur.c+cur.b-v2;
nex.b=v2;
nex.a=cur.a;
if(!vis[nex.a][nex.b][nex.c])
{
nex.pre=cur.id;
cnt++;
nex.id=cnt;
state[cnt]=nex;
q.push(nex);
vis[nex.a][nex.b][nex.c]=1;
}
}
}
}
}
return fg;//无解
}
int path[1000000];
void track(int id)//倒推得到分酒步骤
{
int num=0;
int i=id;
int j;
path[++num]=i;
while(state[i].pre!=i)
{
i=state[i].pre;
path[++num]=i;
}
for(j=num;j>=1;j--)
{
cout<<state[path[j]].str ;
}
puts("");
}
int main()
{
int a,b;
int t=BFS(10,7,3,10,0,0,5);
// printf("%d\n",t);
if(t!=-1)
{
for(int i=1;i<=num;i++)
{
printf("第%d种分酒方案如下:\n",i);
track(ids[i]);
}
}
else
{
printf("无解\n");
}
return 0;
}
#include<iostream>
#include<stdio.h>
#include<map>
#include<vector>
#include<queue>
#include<set>
#include<cstdlib>
#include<string.h>
#include<algorithm>
#include<cmath>
using namespace std;
int vis[100][100][100];
char path[100000][2];
int cnt=0;
void dfs(int a,int b,int c,int step)
{
if(a<0 || b<0 || c<0 || a>10 || b>7 || c>3 || vis[a][b][c])
return;
vis[a][b][c]=1;
if(a==5 || b==5 || c==5)
{
cnt++;
printf("第%d种分酒方案如下:\n",cnt);
for(int i=1;i<step;i++)
{
printf("%c->%c ",path[i][0],path[i][1]);
}
puts("");
vis[a][b][c]=0;
return;
}
else
{
//1斤倒满7两
path[step][0]='a';
path[step][1]='b';
dfs(0,a+b,c,step+1);
dfs(a+b-7,7,c,step+1);
//7两倒满1斤
path[step][0]='b';
path[step][1]='a';
dfs(a+b,0,c,step+1);
dfs(10,a+b-10,c,step+1);
//1斤倒满3两
path[step][0]='a';
path[step][1]='c';
dfs(0,b,a+c,step+1);
dfs(a+c-3,b,3,step+1);
//3两倒满1斤
path[step][0]='c';
path[step][1]='a';
dfs(a+c,b,0,step+1);
dfs(10,b,a+c-10,step+1);
//7两倒满3两
path[step][0]='b';
path[step][1]='c';
dfs(a,0,b+c,step+1);
dfs(a,b+c-3,3,step+1);
//3两倒满7两
path[step][0]='c';
path[step][1]='b';
dfs(a,b+c,0,step+1);
dfs(a,7,b+c-7,step+1);
}
}
int main()
{
memset(vis,0,sizeof(vis));
dfs(10,0,0,1);
return 0;
}