不熟悉扩展欧几里得算法的最后去看一下
求cbX+caY=n;的解
求X与Y的最小正整数解(这里的计算是为了第一步的选择如果X<=Y则从B向A到步骤最快,反之从A到B最快)
AC代码
#include<stdio.h>
int f(int a,int b,int &x,int &y){// 用扩展欧几里得算出x,y;
if(b==0){
x=1;
y=0;
return a;
}
int g=f(b,a%b,x,y);
int temp=x;
x=y;
y=temp-a/b*y;
return g;
}
int main(){
int ca,cb,n;
while(scanf("%d%d%d",&ca,&cb,&n)!=EOF){
int x1,y1;
int gcd=f(cb,ca,x1,y1);
x1=((n/gcd)*x1); //求出cbx+cay=n的一个解
x1=(x1%(ca/gcd)+ca/gcd)%(ca/gcd);//求出x1最小正整数解
y1=(y1%(cb/gcd)+cb/gcd)%(cb/gcd);//求出y1的最小正整数解
int k1=x1;
int k2=y1;
int xb=0,xa=0;
if(x1<=y1){ // 如果x1<=y1 则从B向A倒水步骤最优 (即走的步数最少)
while(1){// 这个循环则是模拟倒水过程很简单 应该都会的把
if(xb==n){
printf("success\n");
break;
}
if(xb==0){
k1--;
xb=cb;
printf("fill B\n");
}
if(xa==ca){
k2++;
xa=0;
printf("empty A\n");
}
if(xb!=0){
int l=ca-xa;
if(xb<=l){
printf("pour B A\n");
xa=xa+xb;
xb=0;
}
else {
printf("pour B A\n");
xa=ca;
xb=xb-l;
}
}
}
}
else { //如果不满足x1<=y1 那就是从A向B里面倒水所化步数最少
while(1){
if(xb==n){
printf("success\n");
break;
}
if(xa==0){
k1--;
xa=ca;
printf("fill A\n");
}
if(xb==cb){
xb=0;
printf("empty B\n");
}
if(xa!=0){
int l=cb-xb;
if(xa<=l){
printf("pour A B\n");
xb=xa+xb;
xa=0;
}
else {
printf("pour A B\n");
xb=cb;
xa=xa-l;
}
}
}
}
}
}