题意:给定两个空桶的容量分别为A、B,经过6种操作使获得C升水,求最少操作数;
思路:广搜。最少操作数很简单,练习一下打印路径;打印最短路劲就是每次记录当前状态和上一步,找到终点后查找路径。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define INF 0x3f3f3f3f int A,B,C; int shortest[150][150];//更新最短步数 int quan[510][510];//记录当前操作 int vis[150][150];//标记 int route[500010],num;//最短路径上的操作,及最少操作数 struct node { int x,y; node(){} node(int x,int y) { this->x=x; this->y=y; } }q[500010]; node pre[500][500];//上一个操作 int bfs() { int b=0,e=0; q[e++]=node(0,0); vis[0][0]=1; shortest[0][0]=1; while(b<e) { node now=q[b++]; for(int i=0;i<6;i++) { int xx,yy; if(i==0)//装满1 { xx=A;yy=now.y; if(vis[xx][yy]==1) continue; vis[xx][yy]=1; shortest[xx][yy]=shortest[now.x][now.y]+1; q[e++]=node(xx,yy); quan[xx][yy]=i;//记录当前操作 pre[xx][yy]=now;//记录上一步 } if(i==1)//装满2 { yy=B;xx=now.x; if(vis[xx][yy]==1) continue; vis[xx][yy]=1; shortest[xx][yy]=shortest[now.x][now.y]+1; q[e++]=node(xx,yy); quan[xx][yy]=i; pre[xx][yy]=now; } if(i==2)//清空1 { xx=0;yy=now.y; if(vis[xx][yy]==1) continue; vis[xx][yy]=1; shortest[xx][yy]=shortest[now.x][now.y]+1; q[e++]=node(xx,yy); quan[xx][yy]=i; pre[xx][yy]=now; } if(i==3)//清空2 { yy=0;xx=now.x; if(vis[xx][yy]==1) continue; vis[xx][yy]=1; shortest[xx][yy]=shortest[now.x][now.y]+1; q[e++]=node(xx,yy); quan[xx][yy]=i; pre[xx][yy]=now; } if(i==4)//1倒入2 { if(now.x>=B-now.y) { yy=B;xx=now.x-(B-now.y); } else { yy=now.y+now.x;xx=0; } if(vis[xx][yy]==1) continue; vis[xx][yy]=1; shortest[xx][yy]=shortest[now.x][now.y]+1; q[e++]=node(xx,yy); quan[xx][yy]=i; pre[xx][yy]=now; } if(i==5)//2倒入1 { if(now.y>=A-now.x) { xx=A;yy=now.y-(A-now.x); } else { xx=now.x+now.y;yy=0; } if(vis[xx][yy]==1) continue; vis[xx][yy]=1; shortest[xx][yy]=shortest[now.x][now.y]+1; q[e++]=node(xx,yy); quan[xx][yy]=i; pre[xx][yy]=now; } if(xx==C||yy==C) { int a,b; while(xx!=0||yy!=0)//查找路径 { route[num++]=quan[xx][yy]; a=pre[xx][yy].x; b=pre[xx][yy].y; xx=a;yy=b; } return shortest[now.x][now.y]; } } } return -1; } int main() { int i,j,k,cnt; while(scanf("%d%d%d",&A,&B,&C)!=EOF) { memset(pre,0,sizeof(pre)); memset(quan,0,sizeof(quan)); memset(vis,0,sizeof(vis)); memset(route,0,sizeof(route)); memset(shortest,0,sizeof(shortest)); num=0;temp=INF; cnt=bfs(); if(cnt==-1) printf("impossible\n"); else { printf("%d\n",cnt); for(i=num-1;i>=0;i--) { if(route[i]==0) { printf("FILL(1)\n"); } else if(route[i]==1) { printf("FILL(2)\n"); } else if(route[i]==2) { printf("DROP(1)\n"); } else if(route[i]==3) { printf("DROP(2)\n"); } else if(route[i]==4) { printf("POUR(1,2)\n"); } else if(route[i]==5) { printf("POUR(2,1)\n"); } } } } return 0; }
时间: 2024-10-12 21:40:30