【约瑟夫环变形】UVa 1394 - And Then There Was One

首先看到这题脑子里立刻跳出链表。。后来继续看如家的分析说,链表法时间复杂度为O(n*k),肯定会TLE,自己才意识到果然自个儿又头脑简单了 T^T.

看如家的分析没怎么看懂,后来发现这篇自己理解起来更容易(...)共享一下~http://blog.csdn.net/chenguolinblog/article/details/8873444

问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数。求胜利者的编号。

编号0~(n-1)是有意义的,因为要模n,所以用0-(n-1)更好操作
我们知道第一个人(编号一定是(m-1) mod n) 出列之后,剩下的n-1个人组成了一个新的约瑟夫环(以编号为k=m mod n的人开始):

k k+1 k+2 ... n-2,n-1,0,1,2,... k-2
并且从k开始报0。
现在我们把他们的编号做一下转换:
k --> 0
k+1 --> 1
k+2 --> 2
...
...
k-2 --> n-2
变换后就完完全全成为了(n-1)个人报数的子问题,假如我们知道这个子问题的解:例如x是最终的胜利者,那么根据上面这个表把这个x变回去不刚好就是n个人情况的解吗?!!变回去的公式很简单,相信大家都可以推出来:x‘=(x+k) mod n;

所以我们只要一直重复这个过程便能求得最开始那个人的编号,因为这个人最终的编号是0(只剩他一个人):0->(0+k)%2->((0+k)%2+k)%3->......
f[n]=(f[n-1]+k)%n,f[1]=0;  f[i]表示有i个人时,最后胜利者编号

==========================================

注意此上思路就适用于经典约瑟夫环问题。

==========================================

下面就要变形了...

现在这个问题是从m开始,即是首先(m-1)编号的人出去。。然后就和普通约瑟夫环一样了。故只要我们f[n]=(f[n-1]+m)%n单独算就行了。其他f[i]=(f[i-1]+k)%i;(1<i<n);

代码如下:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 using namespace std;
 6 const int maxn = 10005;
 7 int f[maxn];
 8 int main()
 9 {
10     int n, k, m, step, cnt;
11     while(~scanf("%d%d%d", &n, &k, &m))
12     {
13         if(!n && !k && !m)   break;
14         f[1] = 0;
15         for(int i = 2; i < n; i++)
16         {
17             f[i] = (f[i-1]+k)%i;
18         }
19         int ans = (f[n-1]+m)%n;
20         printf("%d\n", ans+1);
21     }
22     return 0;
23 }
时间: 2024-08-11 07:46:07

【约瑟夫环变形】UVa 1394 - And Then There Was One的相关文章

Poj 3517 And Then There Was One(约瑟夫环变形)

简单说一下约瑟夫环:约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列:依此规律重复下去,直到圆桌周围的人全部出列. 想要求出最后剩下的那个人的在初始的时候的编号的话. f[1]=0; f[i]=(f[i-1]+m)%i;  (i>1) 可以推出剩下i个人内叫到m的时候的编号.注意这是逆推.推到最后初始的时候的情况 #include<stdio.h>

HDU 5643 King&#39;s Game | 约瑟夫环变形

经典约瑟夫环 1 int f[N] ={ 0 }; 2 for(int i=2; i<=n; i++) 3 { 4 f[i] = (f[i-1] + k) % i; 5 } 变形:k是变化的 #include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #include <stdlib.h> #include <queue> #in

poj 1012 &amp; hdu 1443 Joseph(约瑟夫环变形)

题目链接: POJ  1012: http://poj.org/problem?id=1012 HDU 1443: http://acm.hdu.edu.cn/showproblem.php?pid=1443 约瑟夫环(百度百科): http://baike.baidu.com/view/717633.htm?fr=aladdin Description The Joseph's problem is notoriously known. For those who are not famili

(hdu step 2.2.2)Joseph(约瑟夫环变形问题)

题目: Joseph Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2078 Accepted Submission(s): 1204   Problem Description The Joseph\\\\\\\'s problem is notoriously known. For those who are not familiar

UVA - 1394 And Then There Was One

题目大意:给出n,k和m,表示有n个人围成一个圈,从第m个人开始(m也要去掉),每次走k步删除掉,问最后剩下人的序号. 解题思路: 数学递推 分析: 1 题目是一道变形的约瑟夫环变形问题 2 网上看到一篇很好的数学递推法 问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数.求胜利者的编号. 编号0-(n-1)是有意义的,因为要模n,所以用0-(n-1)更好操作 我们知道第一个人(编号一定是(m-1) mod n) 出列之后,剩下的n-1个人组成了

约瑟夫环的变形

问题描述: 输入一个由随机数组成的数列(数列中每个数均是大于0的整数,长度已知),和初始计数值m.从数列首位置开始计数,计数到m后,将数列该位置数值替换计数值m,并将数列该位置数值出列,然后从下一位置从新开始计数,直到数列所有数值出列为止.如果计数到达数列尾段,则返回数列首位置继续计数.请编程实现上述计数过程,同时输出数值出列的顺序. 比如:输入的随机数列为:3,1,2,4,初始计数值m=7,从数列首位置开始计数(数值3所在位置) 第一轮计数出列数字为2,计数值更新m=2,出列后数列为3,1,4

UVALive 3882--And Then There Was One+约瑟夫环问题变形

题目链接:点击进入 题目意思大概和约瑟夫环问题差不多,唯一的不同点在于起点改成了m:刚开始的时候我想直接链表模拟算了,但是后面一看,数据太大,就改用公式做了.约瑟夫环的公式是:f(n)=(f(n-1)+k)%n ,对于这个题起点为m,所以答案就会变成ans=(f(n)+m-k+1)%n; ans有可能小于0,此时我们要给他加上一个n,ans+=n. 代码如下: #include<iostream> #include<cstdio> #include<cstring> #

And Then There Was One(约瑟夫问题变形)

题目链接:http://poj.org/problem?id=3517 And Then There Was One Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5014   Accepted: 2685 Description Let’s play a stone removing game. Initially, n stones are arranged on a circle and numbered 1, …

poj 2886 Who Gets the Most Candies?(线段树+约瑟夫环+反素数)

Who Gets the Most Candies? Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 9934   Accepted: 3050 Case Time Limit: 2000MS Description N children are sitting in a circle to play a game. The children are numbered from 1 to N in clockwise o