9.26T4 CQBZ
1 约瑟夫游戏 (joseph.cpp/c/pas)
1.1问题描述
𝑌 𝐽𝐶 很喜欢玩游戏,今天他决定和朋友们玩约瑟夫游戏。 约瑟夫游戏的规则是这样的:𝑛 个人围成一圈,从1 号开始依次报数,当报到𝑚 时,报1、2、...、m-1 的 人出局,下一个人接着从1 开始报,保证(𝑛 − 1)是(𝑚 − 1)的倍数。最后剩的一个人获胜。 𝑌 𝐽𝐶 很想赢得游戏,但他太笨了,他想让你帮他算出自己应该站在哪个位置上。
1.2 输入格式
从joseph.in读取输入文件。
第一行包含两个整数n 和m,表示人数与数出的人数。
1.3 输出格式
向joseph.out输出你的答案。
输出一行,包含一个整数,表示站在几号位置上能获得胜利。
1.4 样例输入
10 10
1.5
样例输出
10
1.6 数据范围和约定
对于30%的数据,2 ≤ 𝑛 ≤ 1000。
对于70%的数据,2 ≤ 𝑛 ≤ 1000000。
对于100%的数据,2 ≤ 𝑚 ≤ 𝑛 ≤ 2^63 − 1
一道神题,暴力30,然后递推的方法是50分。。。。
100分:找规律(LZY的说法)
别人给出的正解:
考虑每次循环n个人,只会有m倍数的人或者最后n%m的人活下来
此时我们可以旋转环把这n%m放到开头,这就又是一个子问题了,然后递归求解复杂度就非常低了
实际上看到那么大的数据也只能考虑这种复杂度,这题的神奇之处就在于递归。。。。压缩然后求解。。。%%%
code:
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 long long m,n; 5 long long sol(long long beginn,long long siz){ 6 if(siz==1)return 1; 7 long long t=sol(siz%m,siz%m+siz/m); 8 return t*m-beginn; 9 } 10 int main(){ 11 cin>>n>>m; 12 cout<<sol(0,n); 13 }
over