【2015-2016 XVI Open CupI】【交互题 队列筛法】Judgement 赌博机2^20内数循环1的个数为奇数赢 恰好赢到200元钱

I. Interactive Casino
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

This is interactive problem.

In the Interactive Casino game "Binary Roulette" is very popular. Here are the rules of the game.

  • Initially the player has 160 tokens.
  • In one turn player can bet any positive integer amount of tokens, as long as it does not exceed number of tokens player currently has.
  • Inside of slot machine an integer x between 0 and 220 - 1 is generated. If sum of bits of this integer is odd, then player wins (i.e. returns his bet and additional k tokens), otherwise the player loses his bet. Note that player does not know value of x.
  • If the player has zero tokens, game is lost.
  • If the player makes more than 200 bets, game is lost.
  • If the player at some time has 200 tokens, he won the game.

You found on the Algoleaks site that each next integer on the sloth machine is generated using the formula  . Source of x1, unluckly, on this site is not revealed.

Your goal is to ensure the victory.

Input

Your program will receive on the input one integer — number of tokens You currently have or  - 1 in case when game is over by some reason.

Output

If you received  - 1, immediately exit your program with code 0 (otherwise you may get the random verdict from the system). Otherwise, if you received integer T > 0, print one integer between 1 and T, inclusively — your next bet. Dont forget to print end-of-line character and flush the output.

Example
input
160
155
165
180
-1
output
5
10
15
20

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }
const int N = 0, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;
int n;
bool e[1 << 20];
int g[1 << 20];
int win[1 << 20];
int q[1 << 24];
void init()
{
	int top = 1 << 20;
	int mod = top - 1;
	for (LL x = 0; x < top; ++x)
	{
		g[x] = (x * 487237 + 1011807)&mod;
		int y = x;
		int sum = 0;
		while (y){ sum += y & 1; y >>= 1; }
		win[x] = sum & 1;
	}
}
int main()
{
	init();
	int top = 1 << 20;
	int now, nxt;
	scanf("%d",&now);
	int H = 0;
	int T = 0;
	for (int i = 0; i < top; ++i)q[T++] = i;
	bool WIN = 0;
	while (1)
	{
		puts("1");fflush(stdout);
		scanf("%d", &nxt);
		WIN = (nxt == now + 1);
		int t = T;
		while (H < t)
		{
			int x = q[H++];
			if (win[x] == WIN)q[T++] = g[x];
		}
		now = nxt;
		if (T - H == 1&&win[q[H]])
		{
			int more = 200 - now;
			printf("%d\n", more); fflush(stdout);
			return 0;
		}
	}
	return 0;
}
/*
【trick&&吐槽】
1,不要碰到什么题都想着"打表找规律"、"打表找规律"、"打表找规律"
	有的题比如这道,是用筛法一直筛下去就能得到结果的。
2,暴力大法才是王道

【题意】
我们和一个机器赌博
你一开始有160元
1,我们每次可以bet任意一个自己拥有的钱数
2,系统会以x[i]=487237*x[i-1]+1011807 mod 2^20的方式产生新的数。
	如果这个数的 sum of bits 是奇数,我们就赢了自己赌的钱,否则赔。
3,如果我们恰好有200元,不多也不少,我们就赢了
我们希望确保自己会获胜。

你会不断收到一个数字,告诉你在赌博后现有的金钱。
如果这个数字是-1,代表游戏结束了。

【类型】
交互题 队列筛选法

【分析】
这道题一上来想打表找规律,然而并没有找到规律。
看到1^20,应该想到——暴力大法才是王道啊。
这道题正确的做法是暴力。
我们直接把[0,1<<20)的所有数扔到队列列,把不满足规则的数都筛掉。
重复多次,直到只剩下一个合法的数(必然会有只剩下一个数的时候)
这时我们就直到输赢了,就可以AC了。

【时间复杂度&&优化】
O(2^21)

*/


你可能感兴趣的:(codeforces,交互题,题库-CF,筛数思想)