1117-三個水杯
阿新 • • 發佈:2019-01-02
1117 - 三個水杯
時間限制:1秒 記憶體限制:128兆
題目描述
給出三個水杯,大小不一,並且只有最大的水杯的水是裝滿的,其餘兩個為空杯子。三個水杯之間相互倒水,並且水杯沒有標識,只能根據給出的水杯體積來計算。現在要求你寫出一個程式,使其輸出使初始狀態到達目標狀態的最少次數。
輸入
第一行一個整數N(0<N<50)表示N組測試資料
接下來每組測試資料有兩行,第一行給出三個整數V1 V2 V3 (V1>V2>V3 V1<100 V3>0)表示三個水杯的體積。
第二行給出三個整數E1 E2 E3 (體積小於等於相應水杯體積)表示我們需要的最終狀態
輸出
每行輸出相應測試資料最少的倒水次數。如果達不到目標狀態輸出-1
樣例輸入
2
6 3 1
4 1 1
9 3 2
7 1 1
樣例輸出
3
-1
三個水杯問題其實就是對水杯裡面的水進行互相倒的過程,我們可以用三維陣列來標記每一次倒水後的狀態,如果在倒水後發現之前出現過這個狀態,那麼就說明此時已經重複操作了,return出去就好
下面是dfs暴力程式碼
#include<stdio.h> #include<string.h> int zt[105][105][105]; int sa,sb,sc; int flag,step; int ea,eb,ec; void dfs(int a,int b, int c,int num) { if(flag==1&&num>step)//如果所需次數大於之前成功狀態時的次數,返回上一步操作 return ; if(a==ea&&b==eb&&c==ec)//滿足最終狀態條件,進行判斷 { if(step==0)//第一次的成功狀態 step=num; else//不止一次能夠達到成功狀態 { if(step>num) step=num; } flag=1; return ; } for(int i=1;i<=6;i++) { if(i==1)//a向b倒水 { if(a>sb-b&&b!=sb)//a水杯向b水杯倒水,能將b水杯倒滿的情況 { int x=b; a=a-sb+x; b=sb; if(zt[a][b][c]==1) { b=x; a=a-x+sb; continue ; } zt[a][b][c]=1; dfs(a,b,c,num+1); zt[a][b][c]=0; b=x; a=a-x+sb; } else//a向b倒水,把a水杯倒空的情況 { if(a!=0) { int x=a; b=b+x; a=0; if(b<=sb) { if(zt[a][b][c]==1) { a=x; b=b-x; continue ; } zt[a][b][c]=1; dfs(a,b,c,num+1); zt[a][b][c]=0; } a=x; b=b-x; } } } if(i==2)//a向c倒水 { if(a>sc-c&&c!=sc) //將c倒滿 { int x=c; a=a-sc+c; c=sc; if(zt[a][b][c]==1) { a=a-x+sc; c=x; continue ; } zt[a][b][c]=1; dfs(a,b,c,num+1); zt[a][b][c]=0; a=a-x+sc; c=x; } else//將a倒空 { if(a!=0) { int x=a; c=c+a; a=0; if(c<=sc) { if(zt[a][b][c]==1) { a=x; c=c-x; continue ; } zt[a][b][c]=1; dfs(a,b,c,num+1); zt[a][b][c]=0; } a=x; c=c-x; } } } if(i==3)//b向a倒水 { if(b<sa-a)//將b倒空 { if(b!=0) { int x=b; a=a+b; b=0; if(a<=sa) { if(zt[a][b][c]==1) { b=x; a=a-x; continue ; } zt[a][b][c]=1; dfs(a,b,c,num+1); zt[a][b][c]=0; } b=x; a=a-x; } } else//將a倒滿 { int x=a; b=b-sa+a; a=sa; if(zt[a][b][c]==1) { a=x; b=b-x+sa; continue ; } zt[a][b][c]=1; dfs(a,b,c,num+1); zt[a][b][c]=0; a=x; b=b-x+sa; } } if(i==4)//b向c倒水 { if(b>sc-c&&c!=sc)//將c倒滿 { int x=c; b=b-sc+c; c=sc; if(zt[a][b][c]==1) { b=b-x+sc; c=x; continue ; } zt[a][b][c]=1; dfs(a,b,c,num+1); zt[a][b][c]=0; b=b-x+sc; c=x; } else//將b倒空 { if(b!=0) { int x=b; c=c+b; b=0; if(c<=sc) { if(zt[a][b][c]==1) { b=x; c=c-x; continue ; } zt[a][b][c]=1; dfs(a,b,c,num+1); zt[a][b][c]=0; } b=x; c=c-x; } } } if(i==5)//c向a倒水 { if(c>sa-a&&a!=sa)//將a倒滿 { int x=a; c=c-sa+a; a=sa; if(zt[a][b][c]==1) { c=c-x+sa; a=x; continue ; } zt[a][b][c]=1; dfs(a,b,c,num+1); zt[a][b][c]=0; c=c-x+sa; a=x; } else//將c倒空 { if(c!=0) { int x=c; a=a+c; c=0; if(zt[a][b][c]==1) { a=a-x; c=x; continue ; } zt[a][b][c]=1; dfs(a,b,c,num+1); zt[a][b][c]=0; a=a-x; c=x; } } } if(i==6)//c向b倒水 { if(c>sb-b&&b!=sb)//將b倒滿 { int x=b; c=c-sb+b; b=sb; if(zt[a][b][c]==1) { b=x; c=c-x+sb; continue ; } zt[a][b][c]=1; dfs(a,b,c,num+1); zt[a][b][c]=0; b=x; c=c-x+sb; } else//將c倒空 { int x=c; b=b+c; c=0; if(b<=sb) { if(zt[a][b][c]==1) { c=x; b=b-x; continue ; } zt[a][b][c]=1; dfs(a,b,c,num+1); zt[a][b][c]=0; } c=x; b=b-x; } } } } int main() { int n; scanf("%d",&n); while(n--) { scanf("%d %d %d",&sa,&sb,&sc); scanf("%d %d %d",&ea,&eb,&ec); if(sa==ea&&eb==0&&ec==0) printf("0\n"); else { zt[sa][0][0]=1; dfs(sa,0,0,0); if(step!=0) printf("%d\n",step); if(step==0) printf("-1\n"); } step=0; flag=0; memset(zt,0,sizeof(zt)); } }
以下為向xzl借鑑的bfs程式碼,思路是一樣的,程式碼中不再做說明
#include<iostream> #include<queue> #include<string.h> using namespace std; int v1,v2,v3; int e1,e2,e3; struct Node { int x,y,z,step; Node(){} Node(int xx,int yy,int zz,int ss) : x(xx) , y(yy) , z(zz) ,step(ss) {} }; int book[110][110][110]; int bfs(int x,int y,int z,int ss) { memset(book,0,sizeof(book)); queue<Node> Q; Q.push(Node(x,y,z,ss)); book[x][y][z] = 1 ; while(!Q.empty()) { Node u = Q.front(); Q.pop(); if(u.x==e1&&u.y==e2&&u.z==e3) { return u.step ; } for(int i = 0 ; i < 6 ; i++) { Node s = u ; if(i == 0 ) // a - b { int minn = min(s.x , v2 - s.y); s.x-=minn; s.y+=minn; } if(i == 1 ) // a - c { int minn = min(s.x , v3 - s.z); s.x-=minn; s.z+=minn; } if(i == 2 ) // b - a { int minn = min(s.y , v1 - s.x); s.x+=minn; s.y-=minn; } if(i == 3 ) // b - c { int minn = min(s.y , v3 - s.z); s.z+=minn; s.y-=minn; } if(i == 4 ) // c - b { int minn = min(s.z , v2 - s.y); s.z-=minn; s.y+=minn; } if(i == 5 ) // c - a { int minn = min(s.z , v1 - s.x); s.x+=minn; s.z-=minn; } int sss = u.step + 1 ; if(book[s.x][s.y][s.z] == 0) { Q.push(Node(s.x,s.y,s.z,sss)); book[s.x][s.y][s.z] = 1 ; } } } return -1; } int main() { int n; scanf("%d",&n); while(n--) { scanf("%d %d %d",&v1,&v2,&v3); scanf("%d %d %d",&e1,&e2,&e3); int ans = bfs(v1 , 0, 0 ,0); printf("%d\n",ans); } }