CF1729E Guess the Cycle Size#820(div.3)

题目链接

https://codeforces.com/problemset/problem/1729/E

交互题

题意简述

现有一个有 \(n\) 个结点的无向图,这个图是一个循环图(圈状):这个循环图的边数恰好是 \(n\) ,这个图的点从 \(1\)\(n\)编号 ,点的顺序是任意的.你可以以这种方式
\(?\) \(a\) \(b\)
以询问 \(a\)\(b\) 之间的距离,如果 \(a\) 或者 \(b\) 超过了 \(n\) ,则给你返回\(-1\),给你最多50次询问机会,你需要以如下方式
\(!\) \(n\)
回答你判断的图中点的个数
注意,\(?\) \(a\) \(b\)\(?\) \(b\) \(a\) 的值可能不同.交互器会以相同的概率选择两个顶点之间路径之一.
图中的顶点是随机放置的,点的位置是固定的

数据范围

\(1\leq a,b\leq10^{18} , 3\leq n\leq10^{18}\)

样例

点击查看样例

image

分析

图中至少有三个点,我们可以从 \(3\) 一个一个往后询问它与 \(1\) 的距离
如果\(?\) \(i\) \(1\)\(?\) \(1\) \(i\)是相同的且都不是-1,我们得不到什么有效信息,接着往后找
如果\(?\) \(i\) \(1\)\(-1\) ,说明图中有 \(i-1\)个点了(因为我们从\(3\)一直到 \(i-1\) 这些点都能到达1,但是第\(i\)个点不行,肯定就只有\(i-1\)个点了)
如果\(?\) \(a\) \(b\)\(?\) \(b\) \(a\) 不同,因为这个图是一个 \(n\) 条边的循环图( 圈状 ),点\(i\)无非就只有两种走法:
\(i\) 走到 \(1\) 或者从 \(i\) 走到 \(n\) 再走到 \(1\).前一种走法步数是 \(i-1\),后一种走法是 \(n-i+1\) 步,加起来就是 \(n!!\)
此时直接输出步数之和就可以了.

代码

点击查看代码
#include<stdio.h>
#include<iostream>
#include<cstdlib>
#include<string.h>
#include<algorithm>
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL query(LL a,LL b)
{
	printf("? %lld %lld",a,b);
	cout<<endl;
	LL res;
	scanf("%lld",&res);
	return res;
}
int main()
{
	//freopen("uva.txt","r",stdin);
	 LL x,y;
	
	for(int i=2;;i++)
	{
		
		x=query(1,i);
		if(x==-1)
		{
			printf("! %d",i-1);
			cout<<endl;
			return 0;
		}
		y=query(i,1);
		if(x!=y)
		{
			printf("! %lld",x+y);
			cout<<endl;
			return 0;
		}
		
	}
	return 0;
}
posted @ 2022-09-15 16:32  LZH_03  阅读(38)  评论(0编辑  收藏  举报