(2020 浙江高三竞赛题)环中取数
将 $1 ~ n$ 的数字按顺时针方向围成一个圆圈,然后从1开始,按顺时针依次隔一个拿走,即拿走$1,3,5, \cdots$, 这个过程一直进行下去,直到剩下最后一个数字,则最后剩下的数字是_____.(n=2020 in the original problem). #include <iostream>
#include <cassert>
#include <vector>
unsigned cycle_remove(unsigned n)
{
assert(n>0);
std::vector<decltype(n)> v(n);
auto debug_output=[&v](unsigned cnt)
{
#ifdef _DEBUG
for(unsigned i=0; i<cnt; ++i)
std::cout<<v<<' ';
std::cout<<std::endl;
#endif
};
for(unsigned i=0; i<n; ++i)
{
v=i+1;
}
unsigned cnt = n;
// when off is 0, we remove 0th, 2nd, 4th,...
// when off is 1, we remove1st, 3rd, 5th, ...
int off=0;
debug_output(cnt);
while(cnt!=1)
{
for(unsigned i=0; i<(cnt+off)/2; ++i)
{
v=v;
}
auto oldoff=off;
if( (cnt%2)!= 0 && ++off==2)
{
off=0;
}
cnt = (cnt+oldoff)/2;
debug_output(cnt);
}
return v;
}
int main()
{
for(unsigned u = 3; u<2024; ++u)
std::cout<<u<<"\t\t\t"<<cycle_remove(u)<<std::endl;
return 0;
}
部分输出结果
3 2
4 4
5 2
6 4
7 6
8 8
9 2
10 4
11 6
12 8
13 10
14 12
15 14
16 16
17 2
18 4
19 6
20 8
21 10
22 12
23 14
24 16
25 18
26 20
27 22
28 24
29 26
30 28
31 30
32 32
33 2
34 4
35 6
36 8
37 10
38 12
39 14
40 16
41 18
42 20
43 22
44 24
45 26
46 28
47 30
48 32
49 34
50 36
51 38
52 40
53 42
54 44
55 46
56 48
57 50
58 52
59 54
60 56
61 58
62 60
63 62
64 64
65 2
66 4
67 6
68 8
69 10
70 12
71 14
72 16
73 18
74 20
75 22
76 24
77 26
78 28
79 30
80 32
81 34
82 36
83 38
84 40
85 42
86 44
87 46
88 48
89 50
90 52
91 54
92 56
93 58
94 60
95 62
96 64
97 66
98 68
99 70
100 72
101 74
102 76
103 78
104 80
105 82
106 84
107 86
108 88
109 90
110 92
111 94
112 96
113 98
114 100
115 102
116 104
117 106
118 108
119 110
120 112
121 114
122 116
123 118
124 120
125 122
126 124
127 126
128 128
129 2
130 4
131 6
132 8
133 10
134 12
135 14
136 16
137 18
138 20
139 22
140 24
141 26
142 28
143 30
144 32
145 34
146 36
147 38
148 40
149 42
150 44
151 46
152 48
153 50
154 52
155 54
156 56
157 58
158 60
159 62
160 64
161 66
162 68
163 70
164 72
165 74
166 76
167 78
168 80
169 82
170 84
171 86
172 88
173 90
174 92
175 94
176 96
177 98
178 100
179 102
180 104
181 106
182 108
183 110
184 112
185 114
186 116
187 118
188 120
189 122
190 124
191 126
192 128
193 130
194 132
195 134
196 136
197 138
198 140
199 142
200 144
201 146
202 148
203 150
204 152
205 154
206 156
207 158
208 160
209 162
210 164
211 166
212 168
213 170
214 172
215 174
216 176
217 178
218 180
219 182
220 184
221 186
222 188
223 190
224 192
225 194
226 196
227 198
228 200
229 202
230 204
231 206
232 208
233 210
234 212
235 214
236 216
237 218
238 220
239 222
240 224
241 226
242 228
243 230
244 232
245 234
246 236
247 238
248 240
249 242
250 244
251 246
252 248
253 250
254 252
255 254
256 256
257 2 猴子选大王 做题人生 发表于 2026-1-26 08:35
部分输出结果
f:=If])] northwolves 发表于 2026-1-26 09:13
猴子选大王
有没有什么解析或其它适合手工操作的算法? 做题人生 发表于 2026-1-26 11:40
有没有什么解析或其它适合手工操作的算法?
$$2*(N-2^k)$$ @northwolves, @aimisiyou 感谢! 将1——2020的数字按顺时针方向围成一个圆圈,然后从1开始,按顺时针依次隔2个拿走1个,即拿走 1, 4, 7, ...,这个过程一直进行下去,直到剩下最后一个数字,则最后剩下的数字是_____. 本帖最后由 aimisiyou 于 2026-1-28 08:53 编辑
王守恩 发表于 2026-1-28 06:58
将1——2020的数字按顺时针方向围成一个圆圈,然后从1开始,按顺时针依次隔2个拿走1个,即拿走 1, 4, 7, .. ...
665 本帖最后由 Jack315 于 2026-1-28 18:11 编辑
编程模拟取数过程,最后剩下的是 1992 。下图是完整的模拟过程:
数据文件: