版权声明:本文为博主原创文章,转载请声明原创网址。 https://blog.csdn.net/lagoon_lala/article/details/81291124
题目:
题目疑似有误:示例中“一种方法是……(4,2,1)”可能是(4,2,0)
思路:
系统状态(v0,v1,v2)作为结点,有向图
用结构体存状态和fa指针
MAX=1000
输入abc,x,
倒水操作,把所有结果放入队列
防止成环,vis[][][]
倒水操作:轮流取两杯子,倒入倒出操作(判断剩余容量)
(创建状态结点u,复制原有状态保存ij杯子改变后的值)
杯子i倒入j
杯子i有水,j没满
则倒入 杯子i中的水量与j的剩余容量 中的较小值
处理fa、vis
(剩余容量需要用到最大容量,保存成全局数组比较方便)
V1 v2 v3
V1=0,v2=1
01 0,2 1,2
倒水有2*3个方向,两个杯子值用Tempv[2]只能传递一个方向,6个方向用数组存太麻烦,直接临时用值遍历
在哪里新建结点
知识点:
赋值运算返回值是:赋的值
代码:
//6 3 1 4
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 1000
typedef struct Node{
int v[3];
struct Node *fa;
}node;
bool vis[MAX][MAX][MAX];
int a[3];
void vlu(node* n,int a,int b,int c){
n->v[0]=a;
n->v[1]=b;
n->v[2]=c;
}
node* newnode(){
node* n=(node*)malloc(sizeof(node));
vlu(n,0,0,0);
n->fa=NULL;
return n;
}
node* pour(int i,int j,node* n){
if(n->v[i]&&(a[j]-n->v[j])){
node* u=newnode();
memcpy(u,n,sizeof(*n));
int changev=u->v[i]<=(a[j]-u->v[j])?u->v[i]:(a[j]-u->v[j]);
u->v[i]-=changev;
u->v[j]+=changev;
u->fa=n;
return u;
}else return NULL;
}
node* bfs(int a,int b,int c,int x){
node* q[MAX];
node* temp,*u;
int front=0,rear=0;
node* n=newnode();
vlu(n,a,0,0);
vis[a][0][0]=1;
q[rear++]=n;
while(front<rear){
temp=q[front++];
if(temp->v[0]==x||temp->v[1]==x||temp->v[2]==x)return temp;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
if(i!=j){
//pour中cpy temp建u
if((u=pour(i,j,temp))!=NULL&&!vis[u->v[0]][u->v[1]][u->v[2]]){q[rear++]=u;//检查是否需要保留上一个临时变量
vis[u->v[0]][u->v[1]][u->v[2]]=1;
}
// fa在pour中处理了
}
}
}
}
return NULL;
}
void print_ans(node* n) {//需要从前往后可以再加一个栈保存ans
printf("(%d,%d,%d)",n->v[0],n->v[1],n->v[2]);
if(n->fa!=NULL){
printf("<-");
print_ans(n->fa);
}
}
int main(){
int x;
node *temp;
scanf("%d%d%d%d",&a[0],&a[1],&a[2],&x);
temp=bfs(a[0],a[1],a[2],x);
print_ans(temp);
return 0;
}