【问题描述】
有编号从 1 到 N 的 N 个人坐成一圈报数,报到 M 的人出局,下一位再从1开始,如此持续,直止剩下一位为止,报告此人的编号 X。输入 N,M,求出 X。
【输入格式】
第一行2个正整数N和M。
【输出格式】
一个整数。
【数据规模】
50% 的测试数据中,N,M 最大为20000。
100% 的测试数据中,N,M 最大为2000000。
- (在纸上)尝试寻找依次出圈的人的规律,发现不行
- (在纸上)尝试固定n,枚举m,找出幸存者的规律,太费时间,于是想到暴力打表,发现没规律
- 利用上步程序,固定m,枚举n,发现有规律:
n x(幸存者) m=3
=============
1: 1
2: 2
3: 2
4: 1
5: 4
6: 1
7: 4
8: 7
9: 1
10: 4
11: 7
12: 10
13: 13
14: 2
15: 5
16: 8
17: 11
18: 14
19: 17
20: 20
21: 2
22: 5
23: 8
24: 11
25: 14
26: 17
27: 20
28: 23
29: 26
30: 29
31: 1
32: 4
33: 7
34: 10
35: 13
36: 16
37: 19
38: 22
39: 25
40: 28
41: 31
42: 34
43: 37
44: 40
45: 43
46: 46
47: 2
48: 5
49: 8
50: 11
51: 14
52: 17
53: 20
54: 23
55: 26
56: 29
57: 32
58: 35
59: 38
60: 41
61: 44
62: 47
63: 50
64: 53
65: 56
66: 59
67: 62
68: 65
69: 68
70: 1
71: 4
72: 7
73: 10
74: 13
75: 16
76: 19
77: 22
78: 25
79: 28
80: 31
81: 34
82: 37
83: 40
84: 43
85: 46
86: 49
87: 52
88: 55
89: 58
90: 61
91: 64
92: 67
93: 70
94: 73
95: 76
96: 79
97: 82
98: 85
99: 88
100: 91
- 随着n增加,大多数x都增加3(即m)
- 但是有的x就不是这样,比如n=20和21时,按照上步规律,n=21时,x应该是 20(上一个x) +3=23,但是此时x却是2
- 继续分析,发现2=23 % 21(此时的n)
- 上步规律适用于所有x间断处
- 于是得到x的迭代公式:x=(x+m)%i (i为循环变量,从1到n)
- 因为编号从1开始,所以应输出x+1
#include<bits/stdc++.h>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
int ans=0;
for(int i=1; i<=n; i++) {
ans=(ans+m)%i;
}
cout<<ans+1;
return 0;
}
标签:11,10,13,20,21,23,约瑟夫,幸存者
From: https://www.cnblogs.com/algorithm-hu/p/17997927