源代码:
#include
using namespace std;
const int MAXN = 1000000;
int F[MAXN];
int main()
{
int n;
cin >> n;
int i = 0, p = 0, c = 0;
while (①)
{
if (F[i] == 0)
{
if (②)
{
F[i] = 1;
③;
}
④;
}
⑤;
}
int ans = -1;
for (i = 0; i < n; i++)
if (F[i] == 0)
ans = i;
cout << ans << endl;
return 0;
}
目前第一次遇到的新题型,不过不慌,面对这种题要明白每个变量是干什么的。
提示:(1)(Josephus 问题) 有 个人围成一个圈,依次标号 0 至 − 1。从 0 号开 始,依次 0 , 1 , 0 , 1 , … 交替报数,报到 1 的人会离开,直至圈中只剩下一个人。求最后 剩下人的编号。 试补全模拟程序。
著名的约瑟夫问题,相信学过小学奥数的都明白。
F数组,从后面的0和1来看是标记每个人有没有出局。
变量i,标记现在循环到那个数了。
变量p,没有给条件,暂时不知道用处,不过相信后面会知道。
变量c,存储有多少个人说过1,出局了。
所以一下题目会从我们能做出来的入手,题目会打乱顺序,不过题号不会改变。
题目1:
34.①处应填( )
A.i < n B.c < n C.i < n - 1 D.c < n - 1
答案:D
解析:很明显,i的用处是标记循环到那个数了,不应该填在这个空里。人的总数是n,最后c的值应是n-1。将会加n-1次,所以c 题目3: 36.③处应填( ) A.i++ B.i=(i+1)%n C.c++ D.p^=1 答案:C 解析:对^=不了解的小伙伴看看这个人写的博客,十分简单:C++ ^=异或_Alvin森的博客-CSDN博客_异或c++ 我们对F[]数组进行了标记,那么出局的人多了一位,所以要对c进行自增。 题目5: 38.⑤处应填( ) A.i++ B.i=(i+1)%n C.c++ D.p^=1 答案:B 解析:我们循环一次完毕,应该对下一个数进行循环,并且在其他地方没有对i%n的操作,所以i+1后还要对i进行%n操作,所以选B。 题目2: 35.②处应填( ) A.i%2==0 B.i%2==1 C.p D.!p 答案:C 解析:我们能对p进行^=操作,说明p是代表这个人报的数,如果p==1就说明出局,所以判断为if(p)。 题目4: 37.④处应填( ) A.i++ B.i=(i+1)%n C.c++ D.p^=1 答案:D 解析:p应该把现在的状态进行^=操作,所以选D。