NYOJ 21 三个水杯

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





这是关于广搜的一道题目 代码也只是勉强看懂  希望能给那些和我一样的入门者提供一些思路


#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
struct node
{
    int a,b,c,step;//a,b,c 表示水杯中水的体积 为变量 step为变量,记录倒水的次数 
};


int v1,v2,v3,v11,v22,v33;
bool vis[101][101][101];  //标记情况有没有出现 三维数组 
void init()
{
    scanf("%d%d%d%d%d%d",&v1,&v2,&v3,&v11,&v22,&v33);//输入水杯的容量和要达到的状态 
}
    void bfs()
{
        bool flag=false;
        memset(vis,false,sizeof(vis));
        queue<node> que;  //建立一个队列 
        que.push(node{v1,0,0,0});  //初始化队列的状态 即第一个杯子(最大的杯子)是装满的 
        node n;//建立了一个结构体变量 
        int t;
        while(!que.empty())//如果  que.empty() 等于0   que.empty 队列是否为空的判断条件  此处的意思为 如果队列不是空队列 
   {
            n=que.front(); //n等于队列的对头元素 
   que.pop();//队首元素出队
            if(n.a==v11 && n.b==v22 && n.c==v33)//判断水杯中的水是否是想达到的状态 
   {
                flag=true; 
   break;
            }
            if(vis[n.a][n.b][n.c]) continue;//如果 vis[n.a][n.b][n.c] ==0  跳过 不予考虑 
            vis[n.a][n.b][n.c]=true;


            t=(n.a>=v2-n.b)? v2-n.b:n.a;  // t总是取两个之间较小的一个。 v2-n.b表示现状态与目标状态的差距 
            que.push(node{n.a-t,n.b+t,n.c,n.step+1});//倒水 从a中往b中倒水,将b装满。step+1 


            t=(n.a>=v3-n.c)? v3-n.c:n.a;
            que.push(node{n.a-t,n.b,n.c+t,n.step+1});


            t=(n.b>=v1-n.a)? v1-n.a:n.b;
            que.push(node{n.a+t,n.b-t,n.c,n.step+1});


            t=(n.b>=v3-n.c)? v3-n.c:n.b;
            que.push(node{n.a,n.b-t,n.c+t,n.step+1});


            t=(n.c>=v1-n.a)? v1-n.a:n.c;
            que.push(node{n.a+t,n.b,n.c-t,n.step+1});


            t=(n.c>=v2-n.b)? v2-n.b:n.c;
            que.push(node{n.a,n.b+t,n.c-t,n.step+1});//此六句构成一个循环 每次三个水杯内的水都会改变 直到到达目的状态为止 
        }
        if(flag) printf("%d\n",n.step);
        else printf("-1\n");
    }


int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
{
        init();
        bfs();
    }
    return 0;

}



下面的代码不是用队列

01. #include <iostream>
02. #include <cmath>
03. #include <algorithm>
04. #include <cstring>
05. #include <cstdio>
06. using namespace std;
07. int a[100];
08. int b[100];
09. int v[100];
10. int d[100][100][100];
11. int minn;
12. void fun(int k)
13. {
14. int i;
15. //for(i=0;i<3;i++) cout<<v[i]<<' '; cout<<' '<<k<<endl;
16. for(i=0;i<3;i++)
17. {
18. if(v[i]!=b[i]) break;
19. }
20. if(i==3)
21. {
22. if(minn>k)
23. minn=k;
24. return ;
25. //cout<<k<<endl;
26. }
27. for(i=0;i<3;i++)
28. {
29. for(int j=0;j<3;j++)
30. {
31. if(j==i) continue;
32. if(v[j]<a[j])
33. {
34. int p;
35. int c[100];
36. for(int t=0;t<3;t++)
37. c[t]=v[t];
38. if(v[i]-(a[j]-v[j])>=0)
39. {
40. v[i]=v[i]-(a[j]-v[j]);
41. p=a[j]-v[j];
42. }
43. else
44. {
45. p=v[i];
46. v[i]=0;
47. }
48. v[j]+=p;
49.  
50. if(d[v[0]][v[1]][v[2]]>k)
51. {
52. d[v[0]][v[1]][v[2]]=k;
53. fun(k+1);
54. }
55. for(int t=0;t<3;t++)
56. v[t]=c[t];
57. }
58. }
59. }
60. }
61. int main()
62. {
63. int t;
64. cin>>t;
65. while(t--)
66. {
67. memset(v,0,sizeof(v));
68. memset(d,1000000,sizeof(d));
69. int i;
70. minn=10000000;
71. for(i=0;i<3;i++)
72. cin>>a[i];
73. for(i=0;i<3;i++)
74. cin>>b[i];
75. v[0]=a[0];
76. fun(0);
77. if(minn!=10000000) cout<<minn<<endl;
78. else cout<<"-1"<<endl;
79. }
80. return 0;
81. }


x1y2 x2y3 x3y1-x1y3-x2y1-x3y2 是计算三角形面积的公式中的一部分。 在这个公式中,x1、x2、x3分别表示三角形的三个顶点的x坐标,y1、y2、y3分别表示三角形的三个顶点的y坐标。通过计算这个表达式的值,可以得到三角形的面积。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [TetraCluster:使用并行Java 2库的Java并行程序。 该程序在群集并行计算机上运行,​​以从给定的点集中找到...](https://download.csdn.net/download/weixin_42171208/18283141)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [线性代数有个题,求正交变换x=Qy,化二次型f(x1,x2,x3)=8x1x2+8x1x3+8x2x3为标准型求出特征值](https://blog.csdn.net/weixin_39956182/article/details/115882118)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [nyoj-67-三角形面积(S=(1/2)*(x1y2+x2y3+x3y1-x1y3-x2y1-x3y2))](https://blog.csdn.net/weixin_30492601/article/details/99541033)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值