CodeChef - ELHIDARR Find an element in hidden array 交互+二分

在一个非递减排序的数组中,所有元素都出现了K次,除了一个元素出现次数少于K。本篇介绍了一种通过交互式查询来高效找到这个特殊元素的方法。

There is an array of length N consisting of non-negative integers. The array is sorted in non-decreasing order. Each number in the array appears exactly K times, except one element, which appears at least once, but less than K times. Your task is to identify that element.

This is an interactive problem. You are only given the integer N in the input. Both the array and the value of K are hidden. You are allowed to ask the judge the following queries: What is the value of the element at index i of the array? Identify the value of the element with frequency less than K by asking at most 60 such queries.

Input and Output

The first line of the input contains a single integer T denoting the number of test cases.

For each test case, you should start by reading a single line containing one integer N from the input.

You can interact with the judge using the standard input and output. There are two types of operations: to perform one operation, you should print to the standard output a line containing two space-separated integers type and val.

  • If type = 1, you are asking the judge a query for the value of the element of the array at index val. After printing this line, the judge will print to the standard input a line containing one integer corresponding to the value of the element at index val.
  • If type = 2, you are telling the judge that the element with frequency less than K is val. For each test case, you should perform this operation exactly once at the end. This is not counted towards the 60 queries.

 

Note

Don't forget to flush the standard output after printing each line. It can be done using fflush(stdout) in C/C++, System.out.flush() in Java and sys.out.flush() in Python.

If you ask more than 60 queries, your program will get the verdict Wrong Answer.

Constraints

  • 1 ≤ T ≤ 104
  • 3 ≤ N ≤ 105
  • 2 ≤ K ≤ N - 1
  • each element of the array lies between 1 and 109 inclusive

Example

Input / judge feedback	your output
1
3
						1 2
1
						1 3
5
						1 1
1
						2 5

Explanation

Example case 1: Suppose the array is [1, 1, 5]. Note that the value of K is 2, but it is hidden from you.

In the first query, you request the value of the 2nd element and the judge answers 1. Then you request the value of the 3rd element and the judge answers 5, then the value of the first element and the judge answers 1.

Now, you tell the judge that the answer is 5. You made a total of 3 queries.

题解:因为只有一个种类的比其他的数量的少,所以先确定多的数量 k,然后二分判断2*k 和 2*k+1 若一样 说明少的那个在前面,若不一样说明少的那个在后面,然后最后一个判断即可

#include <iostream>
#include <map>
using namespace std;
map<int,int> a;
int main()
{
	int n,T,l,r,mid,k,t;
	cin>>T;
	while(T--)
	{
		a.clear();
		cin>>n;
		cout<<"1 1"<<endl;
		cin>>a[1];
		l=1,r=n;
		while(l<=r)
		{
			mid=(r+l)>>1;
			cout<<"1 "<<mid<<endl;
			cin>>t;
			if(t==a[1]) l=mid+1,k=mid;
			else r=mid-1;
		}
		if(k+k>n)
		{
			cout<<"1 "<<k+1<<endl;
			cin>>t;
			cout<<"2 "<<t<<endl;
			continue;
		}
	//	cout<<k<<endl;
		cout<<"1 "<<k+1<<endl;
		cin>>a[k+1];
		cout<<"1 "<<k+k<<endl;
		cin>>a[k+k];
		if(a[k+k]==a[k+1])
		{
			cout<<"1 "<<k+k+1<<endl;
			cin>>a[k+k+1];
			if(a[k+k+1]==a[k+1])
			{
				cout<<"2 "<<a[1]<<endl;
				continue; 
			}
			l=1,r=n/k+1;
			while(l<r)
			{
				mid=(l+r)>>1;
				cout<<"1 "<<mid*k<<endl;
				cin>>a[mid*k];
				cout<<"1 "<<mid*k+1<<endl;
				cin>>a[mid*k+1];
				if(a[mid*k]==a[mid*k+1])
					r=mid;
				else
					l=mid+1;
			}
			if(l!=n/k+1)
			{
				cout<<"1 "<<(l-1)*k+1<<endl;
				cin>>a[(l-1)*k+1];
				cout<<"2 "<<a[(l-1)*k+1]<<endl;
			}
			else
			{
				cout<<"1 "<<n<<endl;
				cin>>a[n];
				cout<<"2 "<<a[n]<<endl; 
			}
		}
		else
		{
			cout<<"2 "<<a[k+1]<<endl;
		}
	}
	return 0;
 } 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值