la3882(约瑟夫问题的变种)

来源:互联网 发布:国内高薪职业 知乎 编辑:程序博客网 时间:2024/05/29 02:16
n个数排成一个圈。第一次删除m,以后每数k个数删除一次,求最
个被删除的数。当n=8,k=5,m=3时,删数过程如图1-41所示。
图 1-41
输入格式】

输入包含多组数据。每组数据包含3个整数n,k,m(2≤n≤10000,

1≤k≤10000,1≤m≤n)。输入结束标志为n=k=m=0。
【输出格式】
对于每组数据,输出最后一个被删除的数。

【分析】
本题是约瑟夫问题的变种,唯一的区别就是:原版问题中,从1开始
数数,而在本题中,规定第一个删除的数是m。约瑟夫问题作为链表的经
典应用,出现在很多数据结构与程序设计语言的书籍中。可惜链表法的
时间复杂度为O(nk),无法承受本题这样大的规模。
如果像本题这样只关心最后一个被删除的编号,而不需要完整的删
除顺序,则可以用递推法求解。假设编号为0~n-1的n个数排成一圈,从
0开始每k个数删除一个,最后留下的数字编号记为f(n),则f(1)=
0,f(n)=(f(n-1)+k)%n。为什么呢?因为删除一个元素之后,
可以把所有元素重新编号。

上面的都是大神的那个什么话。。

以下是代码

//原来的约瑟夫环是从0开始报数,现在的是从m-k+1开始报数,#include<cstdio>#include<iostream>using namespace std;int n,m,k;int main(){    ios::sync_with_stdio(0);    while(cin>>n>>k>>m&&n)    {        int f=0;        for(int i=2;i<=n;i++) f=(f+k)%i;        f=(m-k+1+f)%n;//这个k是非常的嚣张啊,大的一比        if(f<=0) f+=n;//这个等于号是不能少的        cout<<f<<endl;    }    return 0;}


原创粉丝点击