TTTTTTTTTTTTTTTTT Gym 100851J Jump 构造

Problem J. Jump
Input file: standard input
Output file: standard output
Consider a toy interactive problem OneMax which is defined as follows. You know an integer n and
there is a hidden bit string S of length n. The only thing you may do is to present the system a bit
string Q of length n, and the system will return the number OneMax(Q) — the number of bits which
coincide in Q and S at the corresponding positions. The name of OneMax problem stems from the fact
that this problem is simpler to explain when S = 111 . . . 11, so that the problem turns into maximization
(Max) of the number of ones (One).
When n is even, there is a similar (but harder) interactive problem called Jump. The simplest way to
describe the Jump is by using OneMax:
Jump(Q) = (
OneMax(Q) if OneMax(Q) = n or OneMax(Q) = n/2;
0 otherwise.
Basically, the only nonzero values of OneMax which you can see with Jump are n (which means you’ve
found the hidden string S) and n/2.
Given an even integer n — the problem size, you have to solve the Jump problem for the hidden string
S by making interactive Jump queries. Your task is to eventually make a query Q such that Q = S.
Interaction protocol
First, the testing system tells the length of the bit string n. Then, your solution asks the queries and
the system answers them as given by the Jump definition. When a solution asks the query Q such that
Q = S, the system answers n and terminates, so if your solution, after reading the answer n, tries reading
or writing anything, it will fail.
The limit on the number of queries is n + 500. If your solution asks a (n + 501)-th query, then you will
receive the “Wrong Answer” outcome. You will also receive this outcome if your solution terminates too
early.
If your query contains wrong characters (neither 0, nor 1), or has a wrong length (not equal to n), the
system will terminate the testing and you will receive the “Presentation Error” outcome.
You will receive the “Time Limit Exceeded” outcome and other errors for the usual violations.
Finally, if everything is OK (e.g. your solution finds the hidden string) on every test, you will receive the
“Accepted” outcome, in this case you will have solved the problem.
Input
The first line of the input stream contains an even number n (2 ≤ n ≤ 1000). The next lines of the input
stream consist of the answers to the corresponding queries. Each answer is an integer — either 0, n/2,
or n. Each answer is on its own line.
Output
To make a query, print a line which contains a string of length n which consists of characters 0 and 1
only. Don’t forget to put a newline character and to flush the output stream after you print your query.
Sample input and output
standard input standard output
2
1
0
1
2
01
11
10
00

题意:首先你输入一个数字n(偶数)(n<=1000),电脑则自动生成一个长度为n的01字符串,你每次可以构造出一个长度为n的01字符串,输入给电脑后电脑进行判定,如果你的字符串与电脑的字符串完全吻合,电脑返回n,如果只有一半吻合,电脑返回n/2,此外电脑返回0;你最多询问n+500次;

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <time.h>
#include <algorithm>
#include <set>
#define MM(a,b) memset(a,b,sizeof(a))
typedef long long ll;
typedef unsigned long long ULL;
const double eps = 1e-8;
const int inf = 0x3f3f3f3f;
const double pi=acos(-1);
using namespace std;
const int N=1e3+8;

char  a[N];
int flag[N];

void revse(int i)
{
     a[i]=!(a[i]-'0')+'0';
}

int main()
{
    int n,x;
    while(~scanf("%d",&n))
    {
        MM(a,'');
        MM(flag,0);
        srand(time(0));
        while(1)
        {
            for(int i=1;i<=n;i++) a[i]=rand()%2+'0';
            printf("%s
",a+1);
            fflush(stdout);
            scanf("%d",&x);
            if(x==n||x==n/2) break;
        }
        if(x==n/2)
        {
            revse(1);
            for(int j=2;j<=n;j++)
            {
                revse(j);
                printf("%s
",a+1);
                fflush(stdout);
                scanf("%d",&x);
                if(x==n) break;
                else if(x==n/2) flag[j]=1;
                revse(j);
            }
            if(x!=n)
            {
                revse(1);
                for(int j=2;j<=n;j++) if(flag[j]) revse(j);
                printf("%s
",a+1);
                fflush(stdout);
                scanf("%d",&x);
                if(x!=n)
                {
                  for(int j=2;j<=n;j++) if(flag[j]) revse(j);
                  revse(1);
                  for(int j=2;j<=n;j++) if(!flag[j]) revse(j);
                  printf("%s
",a+1);
                  fflush(stdout);
                  scanf("%d",&x);
                }
            }
        }
    }
    return 0;
}

  分析:简直神思路。首先不停播下随机数种子生成一个排列,直到系统返回n/2;得到字符串S(并不会很多,用排列组合算下)  然后将第一位数字取反,依次枚举j从2-n位,进行取反。如果最后系统还是返回n/2,说明S中第一位和第j位跟电脑的字符串匹配模式是相同的。

http://blog.csdn.net/miracle_ma/article/details/52214284

 

原文地址:https://www.cnblogs.com/smilesundream/p/5781513.html