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


以前写的,广搜问题,判重的方法是3个水杯的水量,倒一次水相当于走一步

 
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct NODE
{
	int num[3];
	int step;
	struct NODE * next;

}Node;

bool haxi[100][100][100];

int main()
{
	int i , j , k , l , num[3] , n[3];
	Node  *head , *tail , *new_node;

	scanf("%d" , &i);
	while(i--)
	{
		memset(haxi , 0 , sizeof(haxi));
		scanf("%d %d %d" , &num[0] , &num[1] , &num[2]);
		scanf("%d %d %d" , &n[0] , &n[1] , &n[2]);
		if(n[0] > num[0] || n[1] > num[1] || n[2] > num[2] || n[0] + n[1] + n[2] != num[0] )
		{
			printf("-1\n");
			continue;
		}
		if(num[0] == n[0])
		{
			printf("0\n");
			continue;
		}
		new_node = (Node *) calloc(1 , sizeof(Node));
		new_node->num[0] = num[0];
		new_node->num[1] = 0;
		new_node->num[2] = 0;
		haxi[new_node->num[0]][new_node->num[1]][new_node->num[2]] = 1;
		tail = head = new_node;
		for( ; head != NULL ; head = head->next)
		{
			for(j = 0 ; j < 3 ; j ++)
			{
				if(head->num[j] == 0)
					continue;
				for(k = 0 ; k < 3 ; k++)
				{
					if(head->num[k] >= num[k])
						continue;
					if(j == k)
						continue;
					new_node = (Node *)calloc(1 , sizeof(Node));
					for(l = 0 ; l < 4 ; l++)
						new_node->num[l] = head->num[l];
					
					if(head->num[j] > num[k] - head->num[k])
					{
						new_node->num[j] -= num[k] - head->num[k];
						new_node->num[k] = num[k];
					}
					else
					{
						new_node->num[k] += new_node->num[j];
						new_node->num[j] = 0;
					}

					if(haxi[new_node->num[0]][new_node->num[1]][new_node->num[2]] == 1)
					{
						free(new_node);
						continue;
					}
					if(new_node->num[0] == n[0] && new_node->num[1] == n[1] && new_node->num[2] == n[2])
					{
						printf("%d\n" , head->step + 1);
						k = 3 ;
						j = 3;
						for( tail = head , head = head->next  ; head != NULL ; head = head->next )
						{
							free(tail);
							tail = head;
						}
						continue;
					}
					new_node->step  = head->step + 1;
					tail->next = new_node;
					tail = new_node;
					haxi[new_node->num[0]][new_node->num[1]][new_node->num[2]] = 1;
				}
			}
		}
		printf("-1\n");
	}
	return 0;
}        


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
孪生素数是指两个素数之间的差值为2的素数对。通过筛选法可以找出给定素数范围内的所有孪生素数的组数。 在引用的代码中,使用了递归筛选法来解决孪生素数问题。该程序首先使用循环将素数的倍数标记为非素数,然后再遍历素数数组,找出相邻素数之间差值为2的素数对,并统计总数。 具体实现过程如下: 1. 定义一个数组a[N,用来标记数字是否为素数,其中N为素数范围的上限。 2. 初始化数组a,将0和1标记为非素数。 3. 输入要查询的孪生素数的个数n。 4. 循环n次,每次读入一个要查询的素数范围num。 5. 使用两层循环,外层循环从2遍历到num/2,内层循环从i的平方开始,将素数的倍数标记为非素数。 6. 再次循环遍历素数数组,找出相邻素数之间差值为2的素数对,并统计总数。 7. 输出总数。 至此,我们可以使用这个筛选法的程序来解决孪生素数问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [python用递归筛选法求N以内的孪生质数(孪生素数)](https://blog.csdn.net/weixin_39734646/article/details/110990629)[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^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [NYOJ-26 孪生素数问题](https://blog.csdn.net/memoryofyck/article/details/52059096)[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^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

勇敢的炮灰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值