Codeforces Round #385 (Div. 1) B. Hongcow's Game(bitmask)

185 篇文章 0 订阅
116 篇文章 0 订阅

This is an interactive problem. In the interaction section below you will see the information about flushing the output.

In this problem, you will be playing a game with Hongcow. How lucky of you!

Hongcow has a hidden n by n matrix M. Let Mi, j denote the entry i-th row and j-th column of the matrix. The rows and columns are labeled from 1 to n.

The matrix entries are between 0 and 109. In addition, Mi, i = 0 for all valid i. Your task is to find the minimum value along each row, excluding diagonal elements. Formally, for each i, you must find .

To do this, you can ask Hongcow some questions.

A question consists of giving Hongcow a subset of distinct indices {w1, w2, ..., wk}, with 1 ≤ k ≤ n. Hongcow will respond with nintegers. The i-th integer will contain the minimum value of min1 ≤ j ≤ kMi, wj.

You may only ask Hongcow at most 20 questions — he thinks you only need that many questions answered.

When you are ready to answer, print out a single integer  - 1 on its own line, then n integers on the next line. The i-th integer should be the minimum value in the i-th row of the matrix, excluding the i-th element. Do not forget to flush the final answer as well. Printing the answer does not count as asking a question.

You will get Wrong Answer verdict if

  • Your question or answers are not in the format described in this statement.
  • You ask strictly more than 20 questions.
  • Your question contains duplicate indices.
  • The value of k in your question does not lie in the range from 1 to n, inclusive.
  • Your final answer is not correct.
You will get  Idleness Limit Exceeded if you don't print anything or if you forget to flush the output, including for the final answer (more info about flushing output below).
Input

The first line of input will contain a single integer n (2 ≤ n ≤ 1, 000).

Output

To print the final answer, print out the string -1 on its own line. Then, the next line should contain n integers. The i-th integer should be the minimum value of the i-th row of the matrix, excluding elements on the diagonal. Do not forget to flush your answer!

Interaction

To ask a question, print out a single integer k on its own line, denoting the size of your subset. Then, the next line should contain kintegers w1, w2, ... wk. Note, you must flush your output to get a response.

Hongcow will respond by printing out a line with n integers. The i-th integer in this line represents the minimum value of Mi, wj where j is between 1 and k.

You may only ask a question at most 20 times, otherwise, you will get Wrong Answer.

To flush you can use (just after printing an integer and end-of-line):

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

Hacking To hack someone, use the following format

n
M_{1,1} M_{1,2} ... M_{1,n}
M_{2,1} M_{2,2} ... M_{2,n}
...
M_{n,1} M_{n,2} ... M_{n,n}

Of course, contestant programs will not be able to see this input.

题意:给你一个n*n的矩阵,已知矩阵中f i i 对角线元素的值都为0,其余元素的值在1到10^9之间,每次你可以询问每行的至多n个元素(w1,w2..wk),然后会返回n个答案,第i个答案为第i行中你询问的k个元素的最小值,最多可以询问20次,然后要求你输出每行中的最小元素。

分析:凌晨以后还不要打cf了,日常翻车,本来想着能一把上2000的,结果又翻车了还掉了7点rating..

可以按照二进制分组的思想,按n个下标二进制每一位为1或0分成两组询问,这样询问2*log(n)次,可以保证每个元素至少在一次分组中和零元素不在同一组中。

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<queue>
#define INF 2147483640
#define eps 1e-9
#define N 500005
#define MOD 998244353
using namespace std;
int n,m,k,u,v,ans,time,cnt[N],f[N];
bool vis[N];
vector<int> G[N];
int main()
{
	cin>>n;
	for(int i = 0;i < n;i++) f[i] = INF;
	for(int i = 0;i <= log2(n)+1;i++)
	 for(int odd = 0;odd <= 1;odd ++)
	 {
	 	int sum = 0;
	 	for(int j = 0;j < n;j++)
	 	 if(((j&(1<<i))>>i) == odd) sum++;
        if(sum == n || !sum) continue;
        cout<<sum<<endl;
        for(int j = 0;j < n;j++)
         if(((j&(1<<i))>>i) == odd) cout<<j+1<<" ";
        cout<<endl;
        fflush(stdout);
        for(int j = 0;j < n;j++)
        {
            int temp;
            cin>>temp;
            if(((j&(1<<i))>>i) == (odd^1)) f[j] = min(f[j],temp);
        }
	 }
	 cout<<"-1"<<endl;
	 for(int i = 0;i < n;i++) cout<<f[i]<<" ";
	 fflush(stdout);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值