hdu1495 && pku3414
题意:
大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"。
分析:直接搜索+模拟
对于N和M俩个杯子的当前状态,每次都有俩种选择,S->N,S->M,N->S,N->M,M->S,M->N
用了BFS和DFS 个写了一个,写dfs的时候,开了个全局Debug了半天,ORZ
BFS版
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
bool vis[110][110];
short S,N,M,s,n,m;
int ans;
struct state
{
short n,m;
short cnt;
state(short a=0,short b=0,short c=0):n(a),m(b),cnt(c){}
};
queue<state> Q;
void BFS()
{
Q.push(state(0,0,0));
vis[0][0]=true;
state tmp;
while(!Q.empty())
{
tmp=Q.front();
Q.pop();
if((tmp.n==S/2 || tmp.m==S/2)&&(S-(tmp.n+tmp.m))==S/2)
{
ans=tmp.cnt;
return ;
}
s=S-tmp.n-tmp.m,n=tmp.n,m=tmp.m;
if(s!=0)
{
if(s+n>=N)
{
s-=(N-n);
n=N;
}
else {
n+=s;
s=0;
}
if(!vis[n][S-s-n]){
Q.push(state(n,S-s-n,tmp.cnt+1));
vis[n][S-s-n]=true;
}
s=S-tmp.n-tmp.m,n=tmp.n,m=tmp.m;
if(s+m>=M)
{
s-=(M-m);
m=M;
}
else m+=s,s=0;
if(!vis[S-s-m][m]){
Q.push(state(S-s-m,m,tmp.cnt+1));
vis[S-s-m][m]=true;
}
}
s=S-tmp.n-tmp.m,n=tmp.n,m=tmp.m;
if(n!=0)
{
if(!vis[0][m]){
Q.push(state(0,m,tmp.cnt+1));
vis[0][m]=true;
}
if(n+m>=M)
{
n-=(M-m);
m=M;
}
else m+=n,n=0;
if(!vis[n][m]){
Q.push(state(n,m,tmp.cnt+1));
vis[n][m]=true;
}
}
s=S-tmp.n-tmp.m,n=tmp.n,m=tmp.m;
if(m!=0)
{
if(!vis[n][0]){
Q.push(state(n,0,tmp.cnt+1));
vis[n][0]=true;
}
if(m+n>=N)
{
m-=(N-n);
n=N;
}
else n+=m,m=0;
if(!vis[n][m]){
Q.push(state(n,m,tmp.cnt+1));
vis[n][m]=true;
}
}
}
}
int main()
{
while(scanf("%d %d %d",&S,&N,&M)==3 && (S||N||M))
{
if(S%2!=0)
{
puts("NO");
continue;
}
memset(vis,false ,sizeof(vis));
while(!Q.empty())
Q.pop();
ans=-1;
BFS();
if(ans==-1)
puts("NO");
else printf("%d\n",ans);
}
}
DFS版
#include<iostream>
const int inf=0x7fffffff;
const int MAX=105;
using namespace std;
int ans;
int S,N,M;
bool vis[MAX][MAX];
void dfs(int a,int b,int cnt)
{
// cout<<"check"<<vis[0][3]<<endl;
if((a==S/2||b==S/2) && (S-(a+b))==S/2)
{
// cout<<a<<' '<<b<<endl;
if(ans>cnt)
ans=cnt;
return ;
}
int s=S-a-b,n=a,m=b;
if(s!=0)
{
if(s+n>=N)
{
s-=(N-n);
n=N;
}
else n+=s,s=0;
if(!vis[n][m]){
vis[n][m]=1;
// cout<<"S->n"<<endl;
dfs(n,m,cnt+1);
vis[n][m]=0;
// cout<<"fan1 "<<n<<' '<<m<<' '<<vis[n][m]<<endl;
}
s=S-a-b,n=a,m=b;
if(s+m>=M)
{
s-=(M-m);
m=M;
}
else m+=s,s=0;
// printf("%d %d\n",n,m);
// cout<<cnt<<endl;
// cout<<vis[n][m]<<endl;
if(!vis[n][m]){
vis[n][m]=1;
// cout<<"S->m"<<endl;
dfs(n,m,cnt+1);
vis[n][m]=0;
// cout<<"fan2 "<<n<<' '<<m<<' '<<vis[n][m]<<endl;
}
}
s=S-a-b,n=a,m=b;
if(n!=0)
{
if(!vis[0][m]){
vis[0][m]=1;
// cout<<"N->S"<<endl;
dfs(0,m,cnt+1);
vis[0][m]=0;
// cout<<"fan3 "<<0<<' '<<m<<' '<<vis[0][m]<<endl;
}
if(n+m>=M)
{
n-=(M-m);
m=M;
}
else m+=n,n=0;
if(!vis[n][m]){
vis[n][m]=1;
// cout<<"N->m"<<endl;
dfs(n,m,cnt+1);
vis[n][m]=0;
// cout<<"fan4 "<<n<<' '<<m<<' '<<vis[n][m]<<endl;
}
}
s=S-a-b,n=a,m=b;
if(m!=0)
{
if(!vis[n][0]){
vis[n][0]=1;
// cout<<"m->s"<<endl;
dfs(n,0,cnt+1);
vis[n][0]=0;
// cout<<"fan5 "<<n<<' '<<m<<' '<<vis[n][0]<<endl;
}
if(m+n>=N)
{
m-=(N-n);
n=N;
}
else n+=m,m=0;
if(!vis[n][m]){
vis[n][m]=1;
// cout<<"m->n"<<endl;
dfs(n,m,cnt+1);
vis[n][m]=0;
// cout<<"fan6 "<<n<<' '<<m<<' '<<vis[n][m]<<endl;
}
}
}
int main(void)
{
while(scanf("%d %d %d",&S,&N,&M)==3&& (S||N||M))
{
if(S%2!=0)
{
puts("NO");
continue;
}
memset(vis,0,sizeof(vis));
ans=inf;
vis[0][0]=1;
dfs(0,0,0);
if(ans==inf)
puts("NO");
else printf("%d\n",ans);
}
return 0;
}
这是PKU上面一道类似的题目的代码,不同的是,这题目要求保存路径
#include<iostream>
#include<algorithm>
#include<string>
#include<queue>
using namespace std;
struct state
{
int a,b;
string road;
state(int x=0,int y=0,string str=""):a(x),b(y),road(str){}
};
//A : drop A
//B : drop B
//C : A to B
//D : B to A
//E : fill A
//F " fill B
queue<state> Q;
int vis[101][101],A,B,C;
bool success;
string ans;
void BFS()
{
success=false;
Q.push(state(0,0,""));
memset(vis,false,sizeof(vis));
vis[0][0]=true;
while(!Q.empty())
{
state temp=Q.front();
string str=temp.road;
Q.pop();
int a=temp.a,b=temp.b,a1,b1;
if(a==C || b==C)
{
success=true;
ans=temp.road;
return ;
}
if(a!=0 && !vis[0][b])
{
vis[0][b]=true;
Q.push(state(0,b,(str + "A")));
}
if(b!=0 && !vis[a][0])
{
vis[a][0]=true;
Q.push(state(a,0,(str + "B")));
}
if(a!=0 && b!=B)
{
if(a+b<B)
{
b1=a+b;
a1=0;
}
else {
b1=B;
a1=a+b-B;
}
if(!vis[a1][b1])
{
vis[a1][b1]=true;
Q.push(state(a1,b1,(str+"C")));
}
}
if(a!=A && b!=0)
{
if(a+b<A)
{
a1=a+b;
b1=0;
}
else a1=A,b1=a+b-A;
if(!vis[a1][b1])
{
vis[a1][b1]=true;
Q.push(state(a1,b1,(str+"D")));
}
}
if(a!=A && !vis[A][b])
{
vis[A][b]=true;
Q.push(state(A,b,(str+"E")));
}
if(b!=B && !vis[a][B])
{
vis[a][B]=true;
Q.push(state(a,B,(str+"F")));
}
}
}
int main()
{
while(scanf("%d %d %d",&A,&B,&C)==3)
{
while(!Q.empty())
Q.pop();
BFS();
if(!success)
{
puts("impossible");
continue;
}
//cout<<ans<<endl;
int len=ans.length();
printf("%d\n",len);
for(int i=0;i<len;i++)
{
if(ans[i]=='A')
puts("DROP(1)");
else if(ans[i]=='B')
puts("DROP(2)");
else if(ans[i]=='C')
puts("POUR(1,2)");
else if(ans[i]=='D')
puts("POUR(2,1)");
else if(ans[i]=='E')
puts("FILL(1)");
else puts("FILL(2)");
}
}
return 0;
}

浙公网安备 33010602011771号