AcWing 1455. 招聘
宋标 Lv5

题目

某公司招聘,有 个人入围,HR在黑板上依次写下 个正整数 ,然后这 个人围成一个圈,并按照顺时针顺序为他们编号

录取规则是:

第一轮从 号的人开始,取用黑板上的第 个数字,也就是

黑板上的数字按次序循环使用,即如果某轮用了第 个,如果 ,则下一轮需要用第 个;如果 ,则下一轮用第 个。

每一轮按照黑板上的次序取用到一个数字 ,淘汰掉从当前轮到的人开始按照顺时针顺序数到的第 个人。

下一轮开始时轮到的人即为被淘汰掉的人的顺时针顺序下一个人,被淘汰的人直接回家,所以不会被后续轮次计数时数到。

经过 轮后,剩下的最后 人被录取,所以最后被录取的人的编号与 () 相关。

输入格式

输入包含多组测试数据。

第一行包含整数 ,表示共有 组测试数据。

接下来 行,每行包含若干个整数,依次存放 ,表示一组数据。

输出格式

输出共 行,每行对应相应的那组数据确定的录取之人的编号。

数据范围

,
,

输入样例:

1
4 2 3 1

输出样例:

1

样例解释

样例里只有 组测试数据,说的是有 人入围(编号 )。

黑板上依次写下 个数字:,那么:

第一轮:当前轮到 号,数到数字 ,顺时针数第 个人是 号,所以淘汰 号,下一轮从 号开始,目前剩余:

第二轮:当前数到 号,取到数字 ,顺时针数第 个人是 号,所以淘汰 号,下一轮从 号开始,目前剩余:

第三轮:当前轮到 号,循环取到数字 ,顺时针数第 个人是 号,所以淘汰 号,最后只剩下 号,所以录取 号,输出

题解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>

using namespace std;

const int N = 1010;

int a[N];

int main()
{
int t;
cin >> t;
while (t --)
{
int n, m;
cin >> n >> m;

for (int i = 0; i < m; ++ i) scanf("%d", &a[i]);

int ans = 0;
for (int i = 2; i <= n; ++ i)
ans = (ans + a[(n - i) % m]) % i;

cout << ans << endl;
}

return 0;
}

这题注意对应关系,人是从1 ~ N排列, 报数是从0 ~ m-1排列
人与报数的对应关系:
n = a[0]

n-1 = a[1]

n-2 = a[2]

1 = a[n-1]

 评论