And Then There Was One ,Japan LA 3882

题目大意,n个数排成一个圈。第一次删除m,以后每k个数删除一次,求最后一个被删除的数。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 10000+2;
int f[maxn];
int main()
{
    ios::sync_with_stdio(false);
    int n,k,m;
    while(cin>>n>>k>>m)
    {
        if(n+k+m==0)
            return 0;
        f[1]=0;
        for(int i=2;i<=n;i++)
            f[i]=(f[i-1]+k)%i;
        int ans = (m - k +1 +f[n])%n;
        if(ans<=0)
            ans+=n;
        cout<<ans<<endl;
    }
// input.close();
// output.close();
    return 0;
}

题目解析:
很早之前就知道约瑟夫环问题,只不过当时是用模拟的方法做出来的。后来看过具体数学这本神书后才对约瑟夫环的问题有了更加深入的了解,无意间翻了翻刘汝佳的书,又看到了这个问题。数据规模很大,所以用链表模拟的方法肯定卡。所以只能考虑用数学的方法去计算。
编号是0到n-1的n个数排成一圈,从0开始每k个数删除一个,最后留下的数字编号为f(n),则f(1)=0,f(n)=(f(n-1)+k)%n。相当于删除一个元素之后把剩下的元素重新编号。具体数学原理和扩展可以看具体数学这本书。

你可能感兴趣的:(uva,la)