LightOJ - 1179 Josephus Problem(约瑟夫)

Josephus Problem

Time Limit: 2000MS   Memory Limit: 32768KB   64bit IO Format: %lld & %llu

Submit Status

Description

The historian Flavius Josephus relates how, in the Romano-Jewish conflict of 67 A.D., the Romans took the town of Jotapata which he was commanding. Escaping, Josephus found himself trapped in a cave with 40 companions. The Romans discovered his whereabouts and invited him to surrender, but his companions refused to allow him to do so. He therefore suggested that they kill each other, one by one, the order to be decided by lot. Tradition has it that the means for affecting the lot was to stand in a circle, and, beginning at some point, count round, every third person being killed in turn. The sole survivor of this process was Josephus, who then surrendered to the Romans. Which begs the question: had Josephus previously practiced quietly with 41 stones in a dark corner, or had he calculated mathematically that he should adopt the 31st position in order to survive?

Now you are in a similar situation. There are n persons standing in a circle. The persons are numbered from 1 to n circularly. For example, 1 and n are adjacent and 1 and 2 are also. The count starts from the first person. Each time you count up to k and the kth person is killed and removed from the circle. Then the count starts from the next person. Finally one person remains. Given n and k you have to find the position of the last person who remains alive.

Input

Input starts with an integer T (≤ 200), denoting the number of test cases.

Each case contains two positive integers n (1 ≤ n ≤ 105) and k (1 ≤ k < 231).

Output

For each case, print the case number and the position of the last remaining person.

Sample Input

6

2 1

2 2

3 1

3 2

3 3

4 6

Sample Output

Case 1: 2

Case 2: 1

Case 3: 3

Case 4: 3

Case 5: 2

Case 6: 3

Source

Problem Setter: Jane Alam Jan

Submit Status

#include <cstdio>
#define N 100010
int rec[N];
int deal(int n, int k)
{
    rec[1]=0;
    for(int i=2; i<=n; i++)
        rec[i]=(rec[i-1]+k)%i;
    return rec[n]+1;
}
int main()
{
    int t;  int Q=1;
    scanf("%d", &t);
    while(t--)
    {
        int n, k; scanf("%d%d", &n, &k);
        printf("Case %d: %d\n", Q++, deal(n, k));
    }
    return 0;
}

暴力码,  超时 ;

#include <cstdio>
#include <cstring>
#define N 100001
int ps[N], v[N];
using namespace std;
int deal(int n, int k)
{
    int rec, times=0, cnt=0, sumP=0;
    for(int i=1; i<=n; i++)
    {
        if(!v[i]) cnt++;
        if(cnt==k)
        {
            v[i]=1;
            cnt=0;
            sumP++;
            rec=i;
        }
        if(i==n) i=0;
        if(sumP==n) break;
    }
    return rec;
}
int main()
{
    int T; int Q=1;
    scanf("%d", &T);
    while(T--)
    {
        int n, k; memset (v, 0, sizeof(v));
        scanf("%d%d", &n, &k);
        printf("Case %d: %d\n", Q++,  deal(n, k));
    }
    return 0;
}
时间: 2024-08-27 17:29:10

LightOJ - 1179 Josephus Problem(约瑟夫)的相关文章

LightOj 1179 Josephus Problem

1179 - Josephus Problem PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB The historian Flavius Josephus relates how, in the Romano-Jewish conflict of 67 A.D., the Romans took the town of Jotapata which he was commanding. Esc

lightoj 1179(线段树)

传送门:Josephus Problem 题意:经典约瑟夫问题,有n个人,每次数到第k个人出列,求剩下的最后一人. 分析:用线段树模拟约瑟夫问题,记录区间的减少情况,然后根据每次数到的人在区间排第几位,线段树log(n)找到并更新,总复杂度为O(nlog(n)). #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define N 100010 #defin

LightOJ 1070 Algebraic Problem (推导+矩阵快速幂)

题目链接:LightOJ 1070 Algebraic Problem 题意:已知a+b和ab的值求a^n+b^n.结果模2^64. 思路: 1.找递推式 得到递推式之后就是矩阵快速幂了 注意:模2^64,定义成unsigned long long 类型,因为无符号类型超过最大范围的数与该数%最大范围 的效果是一样的. AC代码: #include<stdio.h> #include<string.h> #define LL unsigned long long struct Ma

josephus Problem 中级(使用数组模拟链表,提升效率)

问题描述: 在<josephus Problem 初级(使用数组)>中,我们提出了一种最简单直接的解决方案. 但是,仔细审视代码之后,发现此种方案的效率并不高,具体体现在,当有人出局时,遍历数组仍需要对其进行判断, 这无疑做了无用功,降低了代码效率,在人数多时尤其明显. 解决方案: 当有人出局时,考虑将当前出局的人的前一个人(未出局)的下一个人置为当前出局的下一个人(未出局).这样,便确保了每次对counter的增加都是有效的,遍历到的人都是还没有出局的.大大提升了程序的效率.这其实运用了链表

LightOJ 1070 Algebraic Problem (推导+矩阵高速幂)

题目链接:problem=1070">LightOJ 1070 Algebraic Problem 题意:已知a+b和ab的值求a^n+b^n.结果模2^64. 思路: 1.找递推式 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" > 得到递推式之后就是矩阵高速幂了 注意:模2^64,定

LightOJ 1070 - Algebraic Problem 推导+矩阵快速幂

http://www.lightoj.com/volume_showproblem.php?problem=1070 思路:\({(a+b)}^n =(a+b){(a+b)}^{n-1} \) \((ab)C_{n}^{r}a^{n-r}b{r} = C_{n+2}^{r}a^{n-r+2}b{r} - a^{n+2} - b^{n+2} \) 综上\( f(n) = (a+b)f(n-1)-(ab)f(n-2) \) /** @Date : 2016-12-19-19.53 * @Author

LightOJ 1070 - Algebraic Problem 矩阵快速幂

题链:http://lightoj.com/volume_showproblem.php?problem=1070 1070 - Algebraic Problem PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB Given the value of a+b and ab you will have to find the value of an+bn. a and b not necessar

THE JOSEPHUS PROBLEM

问题描述: 古代刑法中,josephus 被告知与其他人一起围成一个圈,每隔三个人杀掉一个,求在哪个位置可以求生. 我们的问题是将数字围成一个圈,每隔一个数字去掉一个数字,数字从1开始,求最后剩下的数字的位置. 解决方案 当我们的数字是偶数的时候,从1开始,那么我们去掉的数字将是 2 4 6 8 … 当我们开始第二轮去掉数字的时候,将原来位置上面的数字按顺序重新从 1 开始编号,假设新一轮的位置编号为 n ,那么恢复为原来的位置就为 2*n-1.假定 J(2n) 为 2n 个数字围成的圈最后剩下

josephus Problem 初级(使用数组)

问题描述: 这是一个很经典的问题,一桌人一起吃饭,比如有6个人,第一个人从1开始报数,后面的人报的数依次递增,当报出的数为某一个数时,报数的那个人出局,游戏继续.出局的那个人后面的还没有出局的人继续从1开始报数,直到所有的人出局为止.得出出局顺序. 比如有6个人,分别为1,2,3,4,5,6 .报数到3的人出局,则出局顺序应该是:3,6, 4, 2, 5, 1 解决方案: 可以采取对数组置标志位解决,将其置为0表示已出局,则遍历到它的时候,不需要增加计数.置标志位在实际开发中也是比较常见的一种思