约瑟夫环——cc++

tech2022-09-25  95

约瑟夫问题

约瑟夫问题是个著名的问题:N个人围成一圈,第一个人从1开始报数,报M的将被杀掉,下一个人接着从1开始报。如此反复,最后剩下一个,求最后的胜利者。  例如只有三个人,把他们叫做A、B、C,他们围成一圈,从A开始报数,假设报2的人被杀掉。

首先A开始报数,他报1。侥幸逃过一劫。然后轮到B报数,他报2。非常惨,他被杀了C接着从1开始报数接着轮到A报数,他报2。也被杀死了。最终胜利者是C

核心在于关注胜利者的下标位置是怎么变的。每杀掉一个人,其实就是把这个数组向前移动了M位

每杀掉一个人,其实就是把这个数组向前移动了M位。然后逆过来,就可以得到这个递推式。

#include<bits/stdc++.h> using namespace std; int josephus(int n,int m) { if(n==1) return 0; else return (josephus(n-1,m)+m)%n; } int main() { int n,m; cin>>n>>m; cout<<josephus(n,m); return 0 ; }

 

简化之后代码变成循环的过程。

求出的结果是数组中的下标,最终的编号还要加1

把n个人依次排列好,p是数组下标

#include <iostream> using namespace std; int josephus(int n,int m) { int p=0;//p为数组下标 for(int i=2;i<=n;i++)//n=1时只有一个人,直接胜利,否则进行n-1次循环 { p=(p+m)%i; } return p+1;//求出的结果是数组中的下标,最终的编号还要加1 } int main() { int n,m; cin>>n>>m; cout<<josephus(n,m); return 0; }

 

最新回复(0)