codeforce round 742 div1+2.D. Take a Guess(交互题)

D. Take a Guess

做cf也已经有一段时间了,一直听说过交互题,但是没有自己写过,今天自己写了一道交互题。就记录一下一些关于交互题的细节。

首先交互题目的格式就是通过你给评测机发送询问,评测机实时返回你问题的答案,注意的是,当你进行提问后需要清空缓冲区的内容。

这里只介绍c++的用法,如果你是用printf发起提问的,在读取答案之前要输入fflush(stdout)来清空缓存,如果用cout进行提问,记得问题后面带一个endl。会自动帮你清空缓冲区。然后问完问题后,立刻读取问题的答案,通过一定次数的询问就可以解决题目的问题。光说可能不好理解,那么我们就通过这道题目来举个例子。

This is an interactive task

William has a certain sequence of integers a1,a2,…,an in his mind, but due to security concerns, he does not want to reveal it to you completely. William is ready to respond to no more than 2⋅n2⋅n of the following questions:

  • What is the result of a bitwise AND of two items with indices iand j (i≠j)
  • What is the result of a bitwise OR of two items with indices i and j i≠j)

You can ask William these questions and you need to find the kk-th smallest number of the sequence.

Formally the kk-th smallest number is equal to the number at the kk-th place in a 1-indexed array sorted in non-decreasing order. For example in array [5,3,3,10,1][5,3,3,10,1] 44th smallest number is equal to 5, and2nd and 3rd are 3.

Input

It is guaranteed that for each element in a sequence the condition 0≤ai≤109 is satisfied.

Interaction

In the first line you will be given two integers n and k (3≤n≤104,1≤k≤n)which are the number of items in the sequence a and the number k.

After that, you can ask no more than 2⋅n questions (not including the “finish” operation).

Each line of your output may be of one of the following types:

  • “or i j” (1≤i,j≤n,i≠j) , where ii and j are indices of items for which you want to calculate the bitwise OR.
  • “and i j” (1≤i,j≤n,i≠j), where ii and j are indices of items for which you want to calculate the bitwise AND.
  • “finish res”, where res is the kth smallest number in the sequence. After outputting this line the program execution must conclude.

In response to the first two types of queries, you will get an integer xx, the result of the operation for the numbers you have selected.

After outputting a line do not forget to output a new line character and flush the output buffer. Otherwise you will get the “Idleness limit exceeded”. To flush the buffer use:

  • fflush(stdout) in C++
  • System.out.flush() in Java
  • stdout.flush() in Python
  • flush(output) in Pascal
  • for other languages refer to documentation

If you perform an incorrect query the response will be −1−1. After receiving response −1−1 you must immediately halt your program in order to receive an “Incorrect answer” verdict.

input

7 6

2

7

output

and 2 5

or 5 6

finish 5

交互题你很难在本地测试结果,所以只能通过评测机来帮你评测。

题目解析

那么我们下面就看一下这道题,题意大致是,有一个位置的序列,我们每次询问可以问两个位置数的|或者&的值,你可以问2*n个问题,然后输出序列中第k大的值。这道题的核心其实在于一个结论,a[i]+a[j]=a[i]|a[j]+a[i]&a[j].有了这个结论,我们可以先问1和其他所有位置的or和and的结果存起来,然后通过任意两个非1位置的or和and值算出a[1]的值,具体做法是,a[2]+a[3]=x;a[1]+a[2]=y;a[1]+a[3]=z;这三个方程都是我们通过询问可以得到的,xyz的值都有,所以我们可以得到a[1],然后吧其他所有之前的项减去真正的a[1]就能得到正确的序列,排个序就行。询问刚好2n次。

#include<bits/stdc++.h>
using namespace std;
long long int n,k,x,a[100010];
int main()
{
	cin>>n>>k;
	for(int i=2;i<=n;i++)
	{
		cout<<"or 1 "<<i<<endl;
		cin>>a[i];
		cout<<"and 1 "<<i<<endl;
		cin>>x,a[i]+=x;
	}
	cout<<"or 2 3"<<endl;
	cin>>a[0];
	cout<<"and 2 3"<<endl;
	cin>>x;
	a[0]+=x;
	a[1]=(a[2]+a[3]-a[0])/2;
	for(int i=2;i<=n;i++)
	{
		a[i]-=a[1];
	}
	sort(a+1,a+n+1);
	cout<<"finish "<<a[k];
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值