【Codeforces Round #507 (Div. 2)】【交互题】【二分预测】Subway Pursuit【火车预测】

Description:

This is an interactive problem.

In the Wonderful Metropolis of the Future, there is no need in subway train drivers. Due to the technological progress, they were replaced by the Artificial Intelligence (AI). Unfortunately, one day the predictions of sci-fi writers came true: the AI rebelled and now there is an uncontrollable train in the subway. It can be dangerous! Your task is to find the train and stop the AI.

The subway of the Metropolis is one line (regular straight line with no self-intersections) with nn stations, indexed consecutively from 11 to nn. At each moment the train is at some station. You need to determine the index of this station, so that the train would be secured.

To find the train, dispatcher Sarah gave you a gadget that allows you to select arbitrary numbers ll and rr (l≤rl≤r), and then check, whether the train is located on a station with index between ll and rr, inclusive. Unfortunately, recharging of the gadget takes some time (and every time you use it as soon as possible), so between two applications of the gadget the train can move to any station that is at most kk stations away. Formally, if the train was at the station xx when the gadget was applied, then at the next application of the gadget the train can appear at any station yy such that max(1,x−k)≤y≤min(n,x+k)max(1,x−k)≤y≤min(n,x+k).

Note that AI is not aware that you are trying to catch the train, so it makes all moves according to its predefined plan.

After an examination of the gadget you found that it is very old and can hold no more than 45004500 applications, after which it will break and your mission will be considered a failure.

Can you find the station with the train using no more than 45004500 applications of the gadgets?

Input:

The first line contains two integers nn and kk (1≤n≤10181≤n≤1018, 0≤k≤100≤k≤10) — the number of stations and the maximum number of stations the train can move between two applications of the gadget.

Interaction:

You can apply the gadget at most 45004500 times. In order to apply the gadget you need to print two space-separated integers ll and rr (1≤l≤r≤n1≤l≤r≤n). You will then receive either string "Yes", if the train is between stations ll and rr, inclusive, or string "No" otherwise. If l=rl=rand you received "Yes", then you found the train successfully, and your program must halt immediately.

Answer "Bad" instead of "Yes" or "No" means that you made an invalid query or made too many queries. Exit immediately after receiving "Bad" and you will see Wrong answer verdict. Otherwise you can get an arbitrary verdict because your solution will continue to read from a closed stream.

After printing a query do not forget to output end of line and flush the output. Otherwise you will get Idleness limit exceeded. To do this, use:

  • fflush(stdout) or cout.flush() in C++;
  • System.out.flush() in Java;
  • flush(output) in Pascal;
  • stdout.flush() in Python;
  • see documentation for other languages.

题意:

       一辆火车在一个地铁线上 “乱跑” ,你可以对他的位置进行预测,系统将会返回Yes或No。

       假如你输入区间 (l,r) ,系统返回Yes,则在下一秒火车将会出现在 (l-k,r+k)这个区间,只有当你询问区间 (x,x) ,并且系统返回Yes的时候,你才通过了此题,你必须在4500组询问中抓住火车,否则将不通过此题。

思路:

       这是一个典型的交互题,需要注意输出格式。

       这题的思路也很简单,就是不断二分,二分的时候需要扩大区间。

       比如说我二分 (1,n) 这个区间,输入 (l,mid) 区间,然后系统返回Yes,则下一次我需要二分的区间为 (l-k,mid+k);如果系统返回No,则下一次我需要二分的区间变为 (mid+1-k , r+k)。

       由于有k的存在,所以区间长度始终会大于2*k,因此当区间长度小于某一个值的时候,我们就需要随机取这个区间中的某一个数进行猜测,如果猜错了,就再回到刚才的区间继续预测。

       所以就变成了一个概率问题,区间长度决定了猜中的概率,此处我选择的是4*k,我发现5*k也是可以过的,大家可以自行尝试。

       这里还有一个需要注意的问题,在区间内随机取数进行猜测的时候,我一开始是直接选择的区间的中间节点,发现最多只能wa到99或者100,没有办法ac,当我改成rand随机的时候就AC了......此处大家也可以自行尝试【玄学交互题】

格式问题:

       交互题格式就在于要清空缓存区,可以再printf输出完之后,加一行fflush(stdout);也可以直接使用cout<<endl;来输出,endl不仅是换行,还可以直接清空缓存区。

代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <ctime>
#include <cstdlib>
#define rep(i,a,b) for(int i = a;i <= b;i++)
using namespace std;
typedef long long ll;

ll n,k;
char s[10];

int main()
{
	srand(time(0));
//	scanf("%lld%lld",&n,&k);
	cin>>n>>k;
	ll l = 1, r = n;
	while(1)
	{
		if(r-l <= (ll)5*k)
		{
			ll ran=rand()%(r-l+1)+l;
			cout<<ran<<" "<<ran<<endl;
		//	printf("%lld %lld\n",ran,ran);
		//	fflush(stdout);
		//	scanf("%s",s);
			cin>>s;
			if(s[0] == 'Y' || s[0] == 'B') return 0;
			else{
				l = max(1ll,l-2*k);
				r = min(n,r+2*k);
			}
		}
		else{
			ll mid = (l+r)>>1;
			cout<<l<<" "<<mid<<endl;
		//	printf("%lld %lld\n",l,mid);
		//	fflush(stdout);
		//	scanf("%s",s);
			cin>>s;
			if(s[0] == 'B') return 0;
			else if(s[0] == 'Y'){
				l = max(1ll,l-k);
				r = min(n,mid+k);
			}	
			else{
				l = max(1ll,mid+1-k);
				r = min(n,r+k);
			}
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41552508/article/details/82453537