D. Gold Rush

题目:

输入
11
6 4
9 4
4 2
18 27
27 4
27 2
27 10
1 1
3 1
5 1
746001 2984004

输出
YES
YES
NO
NO
YES
YES
NO
YES
YES
NO
NO

思路:

        这道题很有意思的,题目意思要我们从 一堆 n 个黄金中,按照分成的任意堆,按照两堆两堆分成的时候,另一堆应该是 另一堆的一倍

思路图:

 所以,我们可以推出公式:

按照这个公式,进行建树,搜索,这里我建议是用 BFS 搜索每一层,查看是否有符合的 m 个黄金的堆

代码详解如下:

#include <iostream>
#include <queue>
#define ___G std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
using namespace std;

int n;	// 原始黄金个数

int m;	// 目标堆黄金个数

inline bool BFS()
{
	// 开始BFS 判断
	// q 存储每个分成的每个堆
	queue<int>q;
	q.push(n);	// 存储原始黄金个数

	while (q.size())
	{
		// 取出其中的一个堆
		int sum = q.front();
		q.pop();

		if (sum == m)
			return true;
		// 如果这个堆符合我们的目标黄金个数
		// 返回 true 表示 可以分成

		// 如果可以分成 相应的 一个堆是另一个堆的倍数
		// 那么我们开始分
		if (sum % 3 == 0)
		{
			q.push(2 * sum / 3);
			q.push(sum / 3);
		}
	}
	// 如果都没有返回 false
	return false;
}

inline void solve()
{
	cin >> n >> m;
	if (BFS())
	{
		puts("YES");
	}
	else
		puts("NO");
}

int main()
{
	___G;
	int _t;
	cin >> _t;
	while (_t--)
	{
		solve();
	}
	return 0;
}

最后提交:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值