LA3882 And Then There Was One

来源:互联网 发布:网络虚拟手机号 编辑:程序博客网 时间:2024/06/05 19:40

大白书的题。
约瑟夫环的小变种。
我是直接模拟的,286ms+水过了。
正解是大白书上面那样递推求解。
f=(f+k)%i
因为最开始我们需要删除m,那么我们只要使得我们普通的约瑟夫环的第一个删除的编号为m就行了,怎么做到呢?
我们只需要把编号为1的位置移一下就行了,把编号为1的石头移到X位置,是的从X位置开始,经过k次之后到达的是m位置,那么我们就实现了删除m的效果。
那么,这个X位置怎么计算的呢?我们想X经过了k次到达m位置,那么我们只需要把m逆时针推k个位置就是X位置了。因为约瑟夫环是从自己开始数数的,所以我们只需要把m位置逆时针推k-1个位置即可。

ps:同时附上我286ms+的垃圾代码。(数学大法好!)

#include<bits/stdc++.h>using namespace std;vector<int> V;int n,k,m;void mySolve() {//286ms+    V.clear();    for(int i=1; i<=n; ++i) {        if(i^m) {            V.push_back(i);        }    }    int pos=m-1,vs;    for(int ti=2; ti<n; ++ti) {        vs=(int)V.size();        V.erase(V.begin()+(pos+k-1)%vs);        pos=(pos+k-1)%vs;    }    printf("%d\n",V[0]);}int main() {    while(~scanf("%d%d%d",&n,&k,&m),n+m+k) {        int f=0;        for(int i=2; i<=n; i++)            f=(f+k)%i;        cout<<f<<endl;        f=(m-k+1+f)%n;        if(f<=0)f+=n;        printf("%d\n",f);    }    return 0;}
1 0