倒水问题

倒水问题(water)

有两个无刻度标志的水杯,分别可装x升和y升的水。设另一个水缸,可以用来向水杯灌水或从水杯向水缸里倒水,两个水杯之间也可以相互倒水。已知x升的水杯开始是盛满水的,y升的杯子是空的,问如何通过倒水和灌水操作,用最少的步数能在y升的杯子里量出z升水。

输入:

  一行:x,y,z(<=100),整数。中间一个空格隔开。

输出:

  第一行:最少步数s。

  以下共s行,每行两个用空格隔开的整数,第一个表示操作一次后,x杯中的水的数量,第二个整数表示y杯中的水的数量。

样例:

输入:

20 15 10

输出:

 5

step0:20 0(注意step0这一行不输出)

 

step1:5 15

step2:0 15

step3:15 0

step4:15 15

step5:20 10

 

#include

#include

using namespace std;

intf[110][110],b[110][110],head,tail,step,i,j,p[10010],q[10010],a[10010];

void dfs(int l)

{

       if(a[l]==0)

       {

         return;

    }

       dfs(a[l]);

       cout<<"step"<<b[p[l]][q[l]]<<":";

       cout<<p[l]<<""<<q[l]<<endl;

       step++;

       return;

}

int main()

{

       freopen("water.in","r",stdin);

       freopen("water.out","w",stdout);

       intx,y,z;

       cin>>x>>y>>z;

       f[x][0]=1;

       b[x][0]=0;

       tail++;

       p[tail]=x;

       q[tail]=0;

       a[tail]=0;

       while(head

         {

             i=p[head+1];

             j=q[head+1];

             if(i-(y-j)>=0&&f[i-(y-j)][y]==0)//将X倒入Y,使y满

               {

                   f[i-(y-j)][y]=1;

                   tail++;

                p[tail]=i-(y-j);

                q[tail]=y;

                a[tail]=head+1;

                b[i-(y-j)][y]=b[i][j]+1;

               }

             if(i-(y-j)<0)//将X全部倒入Y,Y不满

            if(f[0][i+j]==0&&i!=0)

             {

                  f[0][i+j]=1;

                 tail++;

                p[tail]=0;

                q[tail]=i+j;

                 a[tail]=head+1;

                b[0][i+j]=b[i][j]+1;

             }

             if(j-(x-i)>=0&&f[x][j-(x-i)]==0)//将Y倒入X,使X满

             {

               f[x][j-(x-i)]=1;

               tail++;

              p[tail]=x;

              q[tail]=j-(x-i);

              a[tail]=head+1;

              b[x][j-(x-i)]=b[i][j]+1;

              }

              if (j-(x-i)<0)//将y全部倒入X,X不满

            if(f[j+i][0]==0&&j!=0)

              {

                  f[j+i][0]=1;

                 tail++;

                p[tail]=j+i;

                q[tail]=0;

                a[tail]=head+1;

                b[j+i][0]=b[i][j]+1;

              }

            

             if(f[0][j]==0&&j!=0)//将X全部倒入缸,且保证X,Y不同时空,否则还需重新倒水

             {

             f[0][j]=1;

             tail++;

            p[tail]=0;

            q[tail]=j;

            a[tail]=head+1;

            b[0][j]=b[i][j]+1;

           }

           if (f[i][0]==0&&i!=0)//将Y全部倒入缸

           {

             f[i][0]=1;

             tail++;

            p[tail]=i;

            q[tail]=0;

            a[tail]=head+1;

            b[i][0]=b[i][j]+1;

          }

          if (f[x][j]==0)//将X用缸中的水灌满

           {

             f[x][j]=1;

             tail++;

            p[tail]=x;

            q[tail]=j;

            a[tail]=head+1;

            b[x][j]=b[i][j]+1;

           }

          if (f[i][y]==0) //将Y用缸中的水灌满

          {

             f[i][y]=1;

             tail++;

            p[tail]=i;

            q[tail]=y;

            a[tail]=head+1;

            b[i][y]=b[i][j]+1;

      }

             

             if(q[tail]==z)

              break;

             head++;

       }

       cout<<b[p[tail]][q[tail]]<<endl;

       dfs(tail);

       return0;

}

用水杯中水的状态进行广搜


你可能感兴趣的:(倒水问题)