交互题 1000ms 256MiB

全都看见咯~(困难版)

该比赛已结束,您无法在比赛模式下递交该题目。您可以点击“在题库中打开”以普通模式查看和递交本题。

G. 全都看见咯~(困难版)

简单版和困难版的唯一区别是,在困难版中,1m101 \le m \le 10is_firstis\_first不一定是1,序列 A 也不一定是[1, 2]。

题目描述

这是一道交互题。

在享用了芝士过后,纳西妲想和你玩一个经典游戏:取石子游戏。

游戏中有一堆石子,里面包含 nn 个石子。游戏方式是两个人轮流抓石子,每次可以取走一定数量的石子;如果谁取走了最后的石子,那么他获得胜利。

作为智慧之神,纳西妲已经看到了所有的可能,所以总会选择最优的方案去取石子。虽然如此,聪明的你作为提瓦特的降临者,又是否看到了一种可以胜过纳西妲的方案呢?

注:在本题中,每次可以取走石子的数量会在数据中给出,用一个序列表示。举个例子,如果给定的数据为 [1,2,3][1,2,3],那么就代表每次可以取走 112233个石子;如果为 [1,2,4][1,2,4],就代表每次可以取走1或2或4个石子。

输入格式

第一行三个整数 nn, m(1m10)m(1 \le m \le 10), is_first(0is_first1)is\_first(0 \le is\_first \le 1)

nn 表示这堆石子的石子总数,mm 表示可以取走石子数量的种类数,is_firstis\_first 表示你是否是先手,00 代表纳西妲是先手取石子,11 代表你是先手取石子。

第二行 mm 个整数,用空格隔开,代表可以取走石子数量的序列 AA

序列中的每个数 1ai101 \le a_i \le 10,序列中的数两两不相同。

数据保证序列 AA 中一定包含元素 11,同时数据保证如果你按照最优方案去取石子,一定可以获得胜利。

交互方式

如果你需要进行一次取石子的操作,你 必须 输出一个序列 AA 中的数字,代表你该轮要取的石子数量。

在一轮过程中,如果你是先手,那么在输出结束,并刷新缓冲区后,你可以从标准输入中读入纳西妲这一轮取的石子数;如果你是后手,那么你需要先从标准输入中读入纳西妲这一轮取的石子数,然后输出你的结果,并刷新缓冲区。

注意,在输出结束后,你 必须 刷新缓冲区。 例如,

  • 在C++ 中你可以使用 fflush(stdout)。
  • 在Java 中你可以使用 System.out.flush()。
  • 在Pascal中你可以使用flush(output)
  • 在Python中你可以使用 sys.stdout.flush()

样例输入

17 3 1
1 2 3

2

1

2

3

样例输出

1

2

3

2

1

数据范围及约定

测试点编号 约定 测试点分值
121 \sim 2 m=1,1n10m = 1, 1 \le n \le 10 每个测试点5分
353 \sim 5 A=[1,2,3,...,m],1n10A = [1, 2, 3, ..., m], 1 \le n \le 10
6106 \sim 10 A=[1,2,3,...,m],1n10000A = [1, 2, 3, ..., m], 1 \le n \le 10000
111511 \sim 15 1n100001 \le n \le 10000 每个测试点10分

C语言示例代码

#include <stdio.h>

int main()
{
	int n, m, is_first; 
	scanf("%d%d%d", &n, &m, &is_first);
	
	int a[10];
	for(int i=0; i<m; i++)
		scanf("%d", &a[i]);
	
	int my_answer, na_answer;
	if(!is_first)
	{
		scanf("%d", &na_answer);
		n -= na_answer;
	}	
	
	while(n)
	{
		my_answer = a[0];
		printf("%d\n", my_answer);
        fflush(stdout); // 注意,不要忘记刷新缓冲区!
		n -= my_answer;
		
		if(!n)	break;
		
		scanf("%d", &na_answer);
		n -= na_answer;
	}

 	return 0;
}

C++示例代码

#include <iostream>
#include <vector>

using namespace std;

int main()
{
	int n, m, is_first; 
	cin >> n >> m >> is_first;
	
	vector<int> a(m);
	for(int i=0; i<m; i++)
		cin >> a[i];
	
	int my_answer, na_answer;
	if(!is_first)
	{
		cin >> na_answer;
		n -= na_answer;
	}	
	
	while(n)
	{
		my_answer = a[0];
		cout << my_answer << endl; // cout << endl 之后,会自动刷新缓冲区。
		n -= my_answer;
		
		if(!n)	break;
		
		cin >> na_answer;
		n -= na_answer;
	}

 	return 0;
}

python示例代码

import sys

n, m, is_first = map(int, input().split())
a = list(map(int, input().split()))

my_answer = 0
na_answer = 0

if is_first == 0:
	na_answer = int(input())
	n -= na_answer
	
while n:
	my_answer = a[0]
	print(my_answer)
	sys.stdout.flush()
	n -= my_answer
	
	if n == 0:
		break
	
	na_answer = int(input())
	n -= na_answer

nahida1.jpg

至此,纳西妲的故事结束了。

而从今以后......

就是「你」的故事啦。

2023 NNU 迎新生赛(Freshman Contest)

未参加
状态
已结束
规则
乐多
题目
14
开始于
2023-11-18 8:00
结束于
2023-11-18 22:00
持续时间
14 小时
主持人
参赛人数
132