hdu 3089 约瑟夫环

原来并不知道约瑟夫环还可以递推直接解orz

约瑟夫问题的递推公式:

设f[n]表示一共n个人,数到k出局,这样最后的winner (n个人从0开始标号,即0--n-1)

f[n]=(f[n-1]+k)%n    (注意%n里这个n也是变量

初值f[1]=0

【公式的详细证明可以refer这里:http://blog.csdn.net/a725sasa/article/details/11664375 】

 

不过本题n很大,O(n)仍然会爆

注意到公式中的%n:如果f[n-1]+k小于n,那么就不用再mod了

如果f[n-1]+若干个k还是很小,就可以一次多跳几步

Reference:http://blog.csdn.net/gyarenas/article/details/9073045

 1 //f[1]=0    f[i]=(f[i-1]+m)%i
 2 //ty=(tx+m)%i
 3 #include<iostream>
 4 #include<cstdio>
 5 #include<cstring>
 6 using namespace std;
 7 #define LL long long
 8 LL n,k;
 9 
10 LL solve(LL n,LL k)
11 {
12     LL i=2;
13     LL tx=0;
14     while(i<=n)
15     {
16         LL x=(i-1-tx)%(k-1)?(i-1-tx)/(k-1):(i-1-tx)/(k-1)-1;
17         if(tx+k<i)
18         {
19             if(i+x>n)
20             {
21                 tx=tx+(n+1-i)*k;
22                 return(tx);
23             }
24             tx=tx+x*k;
25             i+=x;
26         }
27         else
28         {
29             tx=(tx+k)%i;
30             i++;
31         }
32     }
33     return(tx);
34 }
35 
36 int main()
37 {
38     while(scanf("%I64d%I64d",&n,&k)!=EOF)
39     {
40         int i=2;
41         LL tx=0;
42         if(k==1)
43         {
44             tx=(n-1)%n;
45         }
46         else
47             tx=solve(n,k);
48         tx=(tx+1)%n;
49         if(tx==0)   tx+=n;
50         printf("%I64d\n",tx);
51     }
52 }
View Code

 

转载于:https://www.cnblogs.com/pdev/p/4506757.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值