倒水c语言,洛谷 P1432 倒水问题

题目

思路

$bfs$

第一遍提交$50$,第二遍就$100$了,qwq

$code$

#include

#include

#include

#include

#include

using namespace std;

int t,ca,cb,n,step,sum;

int a_now[100001],b_now[100001],flag[100001];//a_now、b_now分别记录a、b壶中的水,flag判断当前这一步是从哪里扩展来的

int ans[100001],qwq[100001];//ans存储进行了哪一步操作,qwq是最后的答案

bool vis[1001][1001];//判断是否到达过当前情况

inline int read(){

int x=0;bool f=0;char c=getchar();

while(c'9'){if(c=='-')f=!f;c=getchar();}

while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}

return f?-x:x;

}//读优

inline void write(int x){

if(x<0) putchar('-'),write(-x);

else {if(x/10)write(x/10);putchar(x%10+'0');}

}//输出

void js(int x){

if(flag[x]){

js(flag[x]),step++;

qwq[++sum]=ans[x];

}

return;

}//计算用了几步以及分别是那几步

void bfs(int a,int b){

int head=0,tail=1;

flag[tail]=0;

a_now[tail]=a;

b_now[tail]=b;

vis[a][b]=1;

while(head

head++;

for(register int i=1;i<=6;++i){

if(i==1){

int c=ca,d=b_now[head];

if(!vis[c][d]){

vis[c][d]=1;

tail++,ans[tail]=i;

a_now[tail]=c,b_now[tail]=d;

flag[tail]=head;

if(d==n){js(tail);return;}

}

}//1操作:filla 意为给a灌满水

if(i==2){

int c=a_now[head],d=cb;

if(!vis[c][d]){

vis[c][d]=1;

tail++,ans[tail]=i;

a_now[tail]=c,b_now[tail]=d;

flag[tail]=head;

if(d==n){js(tail);return;}

}

}//2操作:fill b

if(i==3){

int c=0,d=b_now[head];

if(!vis[c][d]){

vis[c][d]=1;

tail++,ans[tail]=i;

a_now[tail]=c,b_now[tail]=d;

flag[tail]=head;

if(d==n){js(tail);return;}

}

}//3操作:empty a 意为将a中水倒空

if(i==4){

int c=a_now[head],d=0;

if(!vis[c][d]){

vis[c][d]=1;

tail++,ans[tail]=i;

a_now[tail]=c,b_now[tail]=d;

flag[tail]=head;

if(d==n){js(tail);return;}

}

}//4操作:empty b

if(i==5){

int c,d,cha=ca-a_now[head];

if(cha>=b_now[head]) d=0,c=a_now[head]+b_now[head];

else c=ca,d=b_now[head]-cha;

if(!vis[c][d]){

vis[c][d]=1;

tail++,ans[tail]=i;

a_now[tail]=c,b_now[tail]=d;

flag[tail]=head;

if(d==n){

js(tail);

return;

}

}

}//5操作:pour ba 意为将b中水倒到a中(直到a满或者b中水没有剩余)

if(i==6){

int c,d;

int cha=cb-b_now[head];

if(cha>=a_now[head]) c=0,d=b_now[head]+a_now[head];

else c=a_now[head]-cha,d=cb;

if(!vis[c][d]){

vis[c][d]=1;

tail++,ans[tail]=i;

a_now[tail]=c;

b_now[tail]=d;

flag[tail]=head;

if(d==n){

js(tail);

return;

}

}

}//6操作:pour a b

}

}

}

int main(){

t=read();

while(t--){

ca=read(),cb=read(),n=read();

bfs(0,0);//搜索

printf("%d ",step);//输出有几步

for(register int i=1;i<=step;++i){//输出答案

write(qwq[i]);

printf(" ");

//printf("%d ",qwq[i]);

}

puts("");//换行

step=sum=0;

memset(vis,0,sizeof(vis));//初始化

}

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值