思路:
有三个容器,每个最大是100,共有100*100*100=1e6种状态,深搜记录一下每种状态和这种状态的最小步数
深搜时遍历每个容器,如果这个容器里有可乐,就尝试着倒入另外两个容器里
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
#define max_ 10010
#define mod 100000007
#define inf 0x3f3f3f3f
struct node
{
int a,b,c;
int step;
node(int a_,int b_,int c_,int t_)
{
a=a_;b=b_;c=c_;step=t_;
}
};
int s,n,m;
queue<struct node>q;
int vis[105][105][105];
bool judge(node zz)
{
if(zz.a==s/2&&zz.b==s/2)
return true;
if(zz.a==s/2&&zz.c==s/2)
return true;
if(zz.b==s/2&&zz.c==s/2)
return true;
return false;
}
int main(int argc, char const *argv[]) {
while(scanf("%d%d%d",&s,&n,&m)!=EOF)
{
if(s==0&&n==0&&m==0)
break;
memset(vis,inf,sizeof vis);
while(!q.empty())
q.pop();
if(s&1)
{
printf("NO\n");
continue;
}
q.push(node(s,0,0,0));
vis[s][0][0]=0;
int f=0;
while(!q.empty())
{
node zz=q.front();
q.pop();
if(judge(zz))
{
printf("%d\n",zz.step);
f=1;
break;
}
if(zz.a!=0)
{
int aa=max(0,zz.a+zz.b-n),bb=min(zz.a+zz.b,n),cc=zz.c,step=zz.step+1;
if(vis[aa][bb][cc]>step)
vis[aa][bb][cc]=step,q.push(node(aa,bb,cc,step));
aa=max(0,zz.a+zz.c-m),bb=zz.b,cc=min(zz.a+zz.c,m);
if(vis[aa][bb][cc]>step)
vis[aa][bb][cc]=step,q.push(node(aa,bb,cc,step));
}
if(zz.b!=0)
{
int aa=min(s,zz.a+zz.b),bb=max(0,zz.a+zz.b-s),cc=zz.c,step=zz.step+1;
if(vis[aa][bb][cc]>step)
vis[aa][bb][cc]=step,q.push(node(aa,bb,cc,step));
aa=zz.a,bb=max(0,zz.b+zz.c-m),cc=min(m,zz.b+zz.c);
if(vis[aa][bb][cc]>step)
vis[aa][bb][cc]=step,q.push(node(aa,bb,cc,step));
}
if(zz.c!=0)
{
int aa=min(s,zz.a+zz.c),bb=zz.b,cc=max(0,zz.a+zz.c-s),step=zz.step+1;
if(vis[aa][bb][cc]>step)
vis[aa][bb][cc]=step,q.push(node(aa,bb,cc,step));
aa=zz.a,bb=min(n,zz.b+zz.c),cc=max(0,zz.b+zz.c-n);
if(vis[aa][bb][cc]>step)
vis[aa][bb][cc]=step,q.push(node(aa,bb,cc,step));
}
}
if(!f)
printf("NO\n");
}
return 0;
}