Keshawn_lu's Blog

找位置问题

字数统计: 708阅读时长: 2 min
2020/02/24 Share

2020.3.1更新

错误理解题目的意思,以为的是每过一轮就要重新排列(导致编号为1的人永远出不去),其实是每出局一个人就自动变成新的圈,然后循环报数。

不过问题不大,只要把每次判断当前未出局人数前的num清零操作取消即可。


首先想说的是确实是已经好久没写博客了,还是自己太懒…和自己感觉没啥特别想写的,所以开学以后学了c#,顺便写一点算法相关的问题吧。


【问题描述】

n 个人围成一圈, 并依次编号1~n。从编号为1 的人开始,按顺时针方向每隔一人选出一个,剩下的人重新围成一圈,如此循环直到剩下两人,这剩下的两人就是幸运儿。如果你想成为最后两个幸运儿,请问开始时应该站在什么位置?(设3<=n<=50)

img

【输入】

开始时的人数n

【输出】

第1 行是选出顺序,第2 行是两名幸运儿的开始位置(按升序排列),位置编号之间用一个空格分开。

【样例输入】

12

【样例输出】

2 4 6 8 10 12 3 7 11 5

1 9


思考:一开始拿到这个题的时候,确实没啥好的想法,然后百度了一波,发现这是约瑟夫环问题,然后看了一些大佬写的代码,讲道理没有特别看懂,然后索性不看了,自己想了想以后好像可以用数组的方法去解决问题。

首先定义一个数组,代表人数,初始值都为false,由于最后只能留下两个人,所以当还没出局的人数大于2时,一直进行循环。

定义一个变量num来存储实际已经间隔的人数,每个人“报数”时num都会加一,当遇到该位置为之前已经出局的人时,将num减一,当num为2时,即代表该位置的人要出局,再将num置为0即可,下面是代码。

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Week2
{
class Problem3
{
static void Main(string[] args)
{
Console.Write("请输入人数:");
int n = Convert.ToInt32(Console.ReadLine()) ;

//初始化
bool[] People = new bool[n + 1];

for(int i = 0; i < n + 1; i++)
{
People[i] = false;
}

int now_count = n; //当前存在人数
int num = 0; //判断间隔的人数
while(now_count > 2)
{
for (int j = 1; j < n + 1; j++)
{
num++;
if(People[j] == true)
{
num -= 1; //当前的人之前已经出局了
}
else if(num == 2)
{
People[j] = true;
Console.Write(j + " ");
now_count -= 1;
num = 0;
}
}
}

Console.WriteLine();

for(int i = 1; i < n + 1; i++)
{
if(People[i] == false)
{
Console.Write(i + " ");
}
}

Console.ReadKey();

}
}
}
CATALOG