以前小时候的智力题。。。。
题目大意:
这个就是以前的接水问题嘛,给你两个锅,装满分别为a,b升水(c<=max(a,b)<=100),问你怎么装出c升水。问你最少的操作步数,并按顺序输出这些操作。
广搜呗,然后在找到终点之后,要输出路径。这里我是用的两个数组并且给所有入过队的状态编号:
id为i的状态执行的操作为f[i] id为i的状态的上一个状态的id为last[i]
#include<iostream> #include<math.h> #include<string.h> #include<queue> #define N 110 using namespace std; int a,b,e; struct time//此时刻,两个锅分别装水ab,已经进行了step步操作 { int a; int b; int id; }; queue<time>q; int f[N*N]={0};//id为i的状态执行的操作为f[i] int last[N*N]={0};//id为i的状态的上一个状态为last[i] bool vis[N][N]={0}; int dis[N][N]={0}; time move(int i,time t) { time x=t; if(i==0) { x.a=a; } if(i==1) { x.b=b; } if(i==2)//把b倒进a { if(x.a+x.b>a) { int t=x.a; x.a=a; x.b=t+x.b-a; } else { x.a=x.a+x.b; x.b=0; } } if(i==3)//把a倒进b { if(x.a+x.b>b) { int t=x.b; x.b=b; x.a=x.a+t-b; } else { x.b=x.a+x.b; x.a=0; } } if(i==4) { x.a=0; } if(i==5) { x.b=0; } return x; } void output(int n,int step) { int out[N*N]={0}; for(int i=step;i>0;i--) { out[i]=f[n]; n=last[n]; } for(int i=1;i<=step;i++) { if(out[i]==0) { cout<<"FILL(1)"<<endl; } if(out[i]==1) { cout<<"FILL(2)"<<endl; } if(out[i]==2) { cout<<"POUR(2,1)"<<endl; } if(out[i]==3) { cout<<"POUR(1,2)"<<endl; } if(out[i]==4) { cout<<"DROP(1)"<<endl; } if(out[i]==5) { cout<<"DROP(2)"<<endl; } } } bool find(time x) { if(x.a==e||x.b==e)return 1; return 0; } int main() { while(cin>>a>>b>>e) { int step; bool flag=0; int n=2; time l; l.a=0; l.b=0; l.id=1; f[1]=1; dis[0][0]=1; vis[0][0]=1; q.push(l); while(!q.empty()) { if(flag==1)break; for(int i=0;i<6;i++)//4中操作 { time t; t=move(i,q.front()); //cout<<t.a<<" "<<t.b<<endl; t.id=n; if(vis[t.a][t.b]==1)continue; if(find(t)) { flag=1; step=dis[q.front().a][q.front().b]; } q.push(t); dis[t.a][t.b]=dis[q.front().a][q.front().b]+1; vis[t.a][t.b]=1; f[n]=i; last[n]=q.front().id; n++; //cout<<n; if(flag==1)break; } q.pop(); } if(flag==1) { cout<<step<<endl; output(n-1,step); } else { cout<<"impossible"<<endl; } memset(vis,0,sizeof(vis)); memset(dis,0,sizeof(dis)); memset(f,0,sizeof(f)); memset(last,0,sizeof(last)); while(!q.empty()) { q.pop(); } } }
注意:ab不可交换,ab不可交换,ab不可交换!
