hdu2925 Musical Chairs && poj3517 And Then There Was One(约瑟夫环)

来源:互联网 发布:中外政治制度专业 知乎 编辑:程序博客网 时间:2024/05/24 06:33


http://acm.hdu.edu.cn/showproblem.php?pid=2925

我嘞个深深地去啊,上次做线段树一直理解不了约瑟夫环,做了一道还是感觉没吃透,这次终于搞定了。。

参考博客:点击打开链接

刚开始一直看不懂,好好看作者的演示图,注意x和x'的含义,还有f[i]是最后胜利者的编号,所以第一个人的f[i]的编号为0,因为怎么数都不可能把离起点最近的人踢掉啊!!

一旦递推公式出来,一切都好办了!!

f[i] = (f[i-1]+k)%i

不过注意上面处理的环是从0~n-1的,踢的数也是第k-1个,所以最后记得加1变回原来的1-n!


#include <stdio.h>#include <algorithm>#include <stdlib.h>#include <string.h>#include <iostream>using namespace std;const int N = 200010;const int INF = 1e8;int main(){   // freopen("in.txt", "r", stdin);    int n, d;    while(~scanf("%d%d", &n, &d))    {        if(n == 0 && d == 0) break;        int ans = 0;        for(int i = 2; i <= n; i ++)            ans = (ans+d)%i;        printf("%d %d %d\n", n, d, ans+1);    }    return 0;}

http://poj.org/problem?id=3517

poj的这个题是上一道加强了下,规定起点为m。处理方法就是减掉最后一层递归专门用来处理这个起点,处理方法一样。


#include <stdio.h>#include <algorithm>#include <stdlib.h>#include <string.h>#include <iostream>using namespace std;const int N = 200010;const int INF = 1e8;int main(){   // freopen("in.txt", "r", stdin);    int n, k, m;    while(~scanf("%d%d%d", &n, &k, &m))    {        if(n == 0 && k == 0 && m == 0) break;        int ans = 0;        for(int i = 2; i < n; i ++)            ans = (ans+k)%i;        ans = (ans+m)%n;        printf("%d\n", ans+1);    }    return 0;}


0 0
原创粉丝点击