NYOJ-21 三个水杯

三个水杯

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 4
描述
给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。
输入
第一行一个整数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


BFS


01. #include <iostream>
02. #include <queue>
03. #include <string.h>
04. using namespace std;
05.  
06. struct node
07. {
08. int sta[3];
09. int step;
10. };
11.  
12. int visit[100][100][100];
13. int v[3],e[3];
14. queue<node> qu;
15.  
16. int check(node x)
17. {
18. if(x.sta[0]==e[0]&&x.sta[1]==e[1]&&x.sta[2]==e[2])
19. return 1;
20. else
21. return 0;
22. }
23.  
24. int bfs(int x,int y,int z)
25. {
26. node t;
27. t.sta[0]=x;
28. t.sta[1]=y;
29. t.sta[2]=z;
30. t.step=0;
31. qu.push(t);
32. while(!qu.empty())
33. {
34. node t1;
35. t1=qu.front();
36. qu.pop();
37. for(int i=0;i<3;i++)
38. for(int j=0;j<3;j++)
39. {
40. if(i!=j)
41. {
42. if(t1.sta[i]&&t1.sta[j]!=v[j])
43. {
44. node t2;
45. t2.sta[0]=t1.sta[0];
46. t2.sta[1]=t1.sta[1];
47. t2.sta[2]=t1.sta[2];
48. t2.step=t1.step+1;
49. if(t1.sta[i]>=v[j]-t1.sta[j])
50. {
51. t2.sta[i]=t1.sta[i]-(v[j]-t1.sta[j]);
52. t2.sta[j]=v[j];
53. }
54. else
55. {
56. t2.sta[i]=0;
57. t2.sta[j]=t1.sta[i]+t1.sta[j];
58. }
59. if(!visit[t2.sta[0]][t2.sta[1]][t2.sta[2]])
60. {
61. if(check(t2))
62. return t2.step;
63. visit[t2.sta[0]][t2.sta[1]][t2.sta[2]]=1;
64. qu.push(t2);
65. }                      
66. }
67. }
68. }
69. }
70. return -1;
71. }
72. int main()
73. {
74. int n;
75. cin>>n;
76. while(n--)
77. {
78. memset(visit,0,sizeof(visit));
79. cin>>v[0]>>v[1]>>v[2];
80. cin>>e[0]>>e[1]>>e[2];
81. if(e[0]==v[0]&&e[1]==0&&e[2]==0)
82. {
83. cout<<"0"<<endl;
84. continue;
85. }
86. visit[v[0]][0][0]=1;
87. cout<<bfs(v[0],0,0)<<endl;
88. }
89. return 0;
90. }
   

再贴一个最优的


01. #include<iostream>
02. #include<cstdio>
03. #include<cstring>
04. #include<algorithm>
05. #include<bitset>
06. using namespace std;
07. #define CLR(arr,val) memset(arr,val,sizeof(arr))
08. bitset<1000000> Hash;
09. const int MAX_STEP=100000;
10. int WQ[MAX_STEP][4],Goal[3],Cap[3],goalval;
11. int head=0,tail=0;
12. void movw(int numfrom,int numto,int other)
13. {
14. int total=WQ[head][numfrom]+WQ[head][numto];
15. WQ[tail][other]=WQ[head][other];
16. WQ[tail][3]=WQ[head][3]+1;
17. if(total>Cap[numto])
18. {
19. WQ[tail][numfrom]=total-Cap[numto];
20. WQ[tail][numto]=Cap[numto];
21. }
22. else
23. {
24. WQ[tail][numfrom]=0;
25. WQ[tail][numto]=total;
26. }
27. int hashval=WQ[tail][0]*10000+WQ[tail][1]*100+WQ[tail][2];
28. if(hashval==goalval) throw WQ[head][3]+1;
29. if(WQ[head][numfrom]!=0 && !Hash[hashval])
30. {
31. Hash[hashval]=true;
32. if(++tail==MAX_STEP) tail=0;
33. }
34. }
35. int main()
36. {
37. int t;
38. scanf("%d",&t);
39. while(t--)
40. {
41. Hash.reset();
42. scanf("%d%d%d%d%d%d",&Cap[0],&Cap[1],&Cap[2],&Goal[0],&Goal[1],&Goal[2]);
43. head=0,tail=0,goalval=Goal[0]*10000+Goal[1]*100+Goal[2];
44. if(Goal[1]==0 && Goal[2]==0 && Goal[0]==Cap[0]) {puts("0");continue;}
45. WQ[tail][0]=Cap[0];WQ[tail][1]=0;WQ[tail][2]=0;WQ[tail][3]=0;
46. ++tail;
47. try{
48. while(head!=tail)
49. {
50. movw(0,1,2);movw(1,2,0);movw(0,2,1);movw(1,0,2);movw(2,1,0);movw(2,0,1);
51. if(++head==MAX_STEP) head=0;
52. }
53. puts("-1");
54. }catch(int step)
55. {
56. printf("%d\n",step);
57. }
58. }
59. }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值