1. 程式人生 > >Codeforces Round #385 (Div. 1) B. Hongcow's Game(bitmask)

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

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次,然後要求你輸出每行中的最小元素。

可以按照二進位制分組的思想,按n個下標二進位制每一位為1或0分成兩組詢問,這樣詢問2*log(n)次,可以保證每個元素至少在一次分組中和零元素不在同一組中。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstdlib>

using namespace std;

int n;
int ans[1005];

int main()
{
    cin>>n;
    for(int i=0;i<=1000;i++)
        ans[i]=1e9;

    int len=log2(n);
    for(int i=0;i<=(len+1);i++)
    {
        for(int f=0;f<=1;f++)
        {
            int sum=0;
            for(int j=1;j<=n;j++)
            {
                if(((j&(1<<i))>>i)==f)
                {
                    sum++;
                }
            }
            if(sum == n || !sum) continue;
            cout<<sum<<endl;
            for(int j=1;j<=n;j++)
            {
                if(((j&(1<<i))>>i)==f)
                {
                   cout<<j<<" ";
                }
            }
            cout<<endl;
            fflush(stdout);
            for(int j=1;j<=n;j++)
            {
                int tp;
                cin>>tp;

                if(((j&(1<<i))>>i)==(f^1))
                    ans[j]=min(ans[j],tp);
            }
        }
    }
    cout<<"-1"<<endl;
    for(int i=1;i<=n;i++)
    {
        cout<<ans[i]<<" ";
    }
    //cout<<endl;
    fflush(stdout);
}