HDU1495(BFS)

非常可乐

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3125    Accepted Submission(s): 1279


Problem Description
大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"。
 

Input
三个整数 : S 可乐的体积 , N 和 M是两个杯子的容量,以"0 0 0"结束。
 

Output
如果能平分的话请输出最少要倒的次数,否则输出"NO"。
 

Sample Input
   
   
   
   
7 4 3 4 1 3 0 0 0
 

Sample Output
   
   
   
   
NO 3
 
 
//没有想到其他的方法,考虑到只有三个瓶子,极端情况最多也就101*101*101个状态,可以搜索;此题求最少次数,相当于不带权值的边求最短路径,直接BFS,当前最多有6条路,不好找规律只能直接处理,代码很长但易于理解!
#include<iostream>
#include<queue>
using namespace std;
int n,m,s;
bool visited[103][103][103];struct node
{
 int N,M,S,step;
};bool Judge(node a)
{
 if(a.M==a.N&&a.S==0||a.M==a.S&&a.N==0||a.N==a.S&&a.M==0)
  return true;
 else 
  return false;
}int bfs()
{
 queue<node>qq;
 node a;
 a.S=s;
 a.M=0;
 a.N=0;
 a.step=0;
 qq.push(a);
 memset(visited,0,sizeof(visited));
 visited[a.S][a.N][a.M]=true;
 while(!qq.empty())
 {
  node b=qq.front();
  qq.pop();
  if(Judge(b))
   return b.step;
  
  
  a.step=b.step+1;
  if(b.S!=0)
  {
   //s倒向m
   if(b.M!=m)
   {
    if(m-b.M>=b.S)
    {
     a.M=b.S+b.M;
     a.S=0;
     a.N=b.N;
     if(!visited[a.S][a.N][a.M])
     {
      visited[a.S][a.N][a.M]=true;
      qq.push(a);
     }
    }
    else 
    {
     a.S=b.S-(m-b.M);
     a.M=m;
     a.N=b.N;
     if(!visited[a.S][a.N][a.M])
     {
      visited[a.S][a.N][a.M]=true;
      qq.push(a);
     }
    }
   }
   //s倒向n
   if(b.N!=n)
   {
    if(n-b.N>=b.S)
    {
     a.N=b.S+b.N;
     a.S=0;
     a.M=b.M;
     if(!visited[a.S][a.N][a.M])
     {
      visited[a.S][a.N][a.M]=true;
      qq.push(a);
     }
    }
    else 
    {
     a.S=b.S-(n-b.N);
     a.N=n;
     a.M=b.M;
     if(!visited[a.S][a.N][a.M])
     {
      visited[a.S][a.N][a.M]=true;
      qq.push(a);
     }
    }
   }
  }
  
  if(b.M!=0)
  {
   //m倒向s
   if(b.S!=s)
   {
    if(s-b.S>=b.M)
    {
     a.S=b.S+b.M;
     a.M=0;
     a.N=b.N;
     if(!visited[a.S][a.N][a.M])
     {
      visited[a.S][a.N][a.M]=true;
      qq.push(a);
     }
    }
    else 
    {
     a.M=b.M-(s-b.S);
     a.S=s;
     a.N=b.N;
     if(!visited[a.S][a.N][a.M])
     {
      visited[a.S][a.N][a.M]=true;
      qq.push(a);
     }
    }
   }
   //m倒向n
   if(b.N!=n)
   {
    if(n-b.N>=b.M)
    {
     a.N=b.M+b.N;
     a.M=0;
     a.S=b.S;
     if(!visited[a.S][a.N][a.M])
     {
      visited[a.S][a.N][a.M]=true;
      qq.push(a);
     }
    }
    else 
    {
     a.M=b.M-(n-b.N);
     a.N=n;
     a.S=b.S;
     if(!visited[a.S][a.N][a.M])
     {
      visited[a.S][a.N][a.M]=true;
      qq.push(a);
     }
    }
   }
  }
  
  if(b.N!=0)
  {
   //n倒向s
   if(b.S!=s)
   {
    if(s-b.S>=b.N)
    {
     a.S=b.S+b.N;
     a.N=0;
     a.M=b.M;
     if(!visited[a.S][a.N][a.M])
     {
      visited[a.S][a.N][a.M]=true;
      qq.push(a);
     }
    }
    else 
    {
     a.N=b.N-(s-b.S);
     a.S=s;
     a.M=b.M;
     if(!visited[a.S][a.N][a.M])
     {
      visited[a.S][a.N][a.M]=true;
      qq.push(a);
     }
    }
   }
   //n倒向m
   if(b.M!=m)
   {
    if(m-b.M>=b.N)
    {
     a.M=b.N+b.M;
     a.N=0;
     a.S=b.S;
     if(!visited[a.S][a.N][a.M])
     {
      visited[a.S][a.N][a.M]=true;
      qq.push(a);
     }
    }
    else 
    {
     a.N=b.N-(m-b.M);
     a.M=m;
     a.S=b.S;
     if(!visited[a.S][a.N][a.M])
     {
      visited[a.S][a.N][a.M]=true;
      qq.push(a);
     }
    }
   }
  }
 }
 return -1;
}int main()
{
 while(~scanf("%d%d%d",&s,&n,&m)&&!(0==s&&0==n&&0==m))
 {
  int ans=bfs();
  if(ans==-1)
   cout<<"NO"<<endl;
  else 
   cout<<ans<<endl;
 }
 return 0;
}


 

你可能感兴趣的:(图论,bfs)