P10026 「HCOI-R1」哀之变化 题解

文章介绍了如何通过逆向操作,如整数除以2和模运算,解决一个编程问题,即用最少步数使n变为1,同时处理剩余次数和边界条件,给出一个C++代码实现。
摘要由CSDN通过智能技术生成


学哥出的题,当然得写个题解啊

题目:

思路:

我们发现如果对 a a a 直接模拟很难处理,所以选择对 n n n 进行逆向操作。

用最少的步数使 n n n 变为 1 1 1,再考虑如何处理多余的次数,若次数不足则直接无解。

于是先分类讨论(第一步):

2 ∣ n 2|n 2∣n,则让 n = n ÷ 2 n=n\div2 n=n÷2

2 ∣ ( n + 1 ) 2|(n+1) 2∣(n+1),则让 n = ( n + 1 ) ÷ 2 n=(n+1)\div2 n=(n+1)÷2

接下来处理剩余的次数。

我们欣喜的发现,竟然有周期哎!

于是乎,若剩余次数大于 1 1 1,则必定有解。

对于剩余 1 1 1 的情况,我们应该尽量将其加入到我们的缩减过程中,但列出式子后,我们发现,在这种情况下,无解。

最后,注意两点:

  1. k = 0 k = 0 k=0 !!!

  2. 不要搞岔!!!

放上代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
	int T , n , m , a , b;
	bool flag = 0;
	cin >> T;
	while(T --)
	{
		m = 0;
		flag = 0;
		b = 0;
		cin >> a >> n;
		if(n == 0)
		{
			if(a != 0)
			{
				cout << "Yes" << endl;
			}
			else
			{
				cout << "No" << endl;
			}
			continue;
		}
		if(n == 1)
		{
			if(a == 1 || a == 3)
			{
				cout << "No" << endl;
			}
			else
			{
				cout << "Yes" << endl;
			}
			continue;
		}
		while(n > 1)
		{
			m ++;
			if(n % 2 == 1)
			{
				if(m == 1)
				{
					flag = 1;
				}
				else
				{
					flag = 0;
				}
			}
			if(n % 2)
			{
				n ++;
				b = 1;
			}
			else
			{
				n /= 2;
			}
		}
		if(((b == 0 || flag) && a - m == 1) || m > a)
		{	
			cout << "No" << endl;
		}
		else
		{
			cout << "Yes" << endl;
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值