E. Guess the Cycle Size

该博客探讨了一种在有限查询次数下预测环形结构大小的问题。题目中,系统随机返回两点间路径长度,允许50次查询。博主首先分析了二分搜索的局限性,然后提出了通过询问(1, n)和(n, 1)来确定环大小的方法,结合概率论中的路径长度出现概率,最终给出了一个解决方案。代码实现中展示了如何在25次查询内找到环的大小。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

E. Guess the Cycle Size

前置知识点:C/C++交互,概率论

题意:有 nnn 个点组成的环,点的编号从 1−n1 - n1n ,要求在只能询问 505050 次的清况下,预测出 nnn 的具体值是多少,nnn 的范围 (3≤n≤1018)(3\leq n \leq 10^{18})(3n1018)

利用 ? a b?\ a\ b? a b 询问两点之间的距离,由于是一个环形,所以会有两条路径,系统为以相同的概率给出其中的一条路径长度。在询问 ? a b?\ a\ b? a b? b a?\ b \ a? b a 时,输出的答案可能不同。

最后将结果以 ! n!\ n! n 的形式输出。

菜鸡思路:刚开始看到这个题目就会感觉这里只需要查看点是否在环上就可以了,如果询问的点不在环上,那么系统会输出 −1-11,所以紧扣这一点,我们能用二分求解问题,但是,这里只有 505050 次的询问机会,如果使用二分求解,那会需要 log21018>50log_{2}^{10^{18}} > 50log21018>50 次,所以二分的求解不太可行。

如果直接用 101810^{18}1018 的值,那连样例都过不了,所以我们可以把数据变换一下,变成 101410^{14}1014 看看结果

在这里插入图片描述

官方题解:先查询 (1,n)(1,n)(1,n) 值 ,如果第一次查询我们得到的答案就是 −1-11 ,那环的大小就是 n−1n-1n1 ,否则 ,那我们再查询 (n,1)(n,1)(n,1) 的值,如果两次的答案相同,那 nnn111 循环上面的操作,如果两次的结果不相同,那环的大小就是两个答案相加。

两条路径长度分别用 x、yx、yxy 表示,xxxyyy 出现的概率相同 (12)(\frac{1}{2})(21)252525 次查询出现不同的值的概率为 1−(12)25≈0.999999971 - (\frac{1}{2})^{25} \approx 0.999999971(21)250.99999997

#include <stdio.h>
#include <algorithm>

using namespace std;
typedef long long ll;

int main(){
	ll k1 = 0,k2 = 0,k = 0;
	ll l = 1,r = 4;
	int L = 25;
	while(L --) {
		printf("? %lld %lld\n",l,r);
		fflush(stdout);
		scanf("%lld",&k1);
		
		printf("? %lld %lld\n",r,l);
		fflush(stdout);
		scanf("%lld",&k2);
		
		if(k1 != k2) {
			k = k1 + k2;
			break;
		}
		else if(k1 == -1) {
			k = r - 1;
			break;
		}
		r ++;
	}
	printf("! %lld\n",k);
	fflush(stdout);
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值