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

posted @ 2018-09-26 19:17  saionjisekai  阅读(31)  评论(0编辑  收藏  举报