题目
某公司招聘,有 个人入围,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]