UVALive 3882 And Then There Was One

题解:

先来探讨约瑟夫问题

常规做法是链表模拟.不多说

递推做法

分析:

第一次:        0.1.2 ..... k-1.k.k+1........n-1

去掉k - 1     0.1.2 .....       k.k+1........n-1

从k开始       k.k+1...... n-1.0.1........ k-2

转换           0.1..........n-2  (转换公式: ( i - k + n ) % n )

第二次        0.1..........n-2

去掉k - 1     0.1.2 .....       k.k+1........n-2

从k开始       k.k+1...... n-2.0.1........ k-2

转换           0.1..........n-3  (转换公式: ( i - k + n - 1 ) % ( n - 1 ) )

........

第n次         0

反向递推

a = 0

第n次的0等价于第n-1次。最后一个删除的数  a = ( a + k  ) % 2

a 等价于第n - 2次。最后一个删除的数         a = ( a + k ) % 3

......

a = ( a + k ) % n

那么递推公式出来了

a = 0;
for( int i = 2; i <= n; i ++ ) a = ( a + k ) % i;

再根据m - 1 与 k - 1 的相对位置判断即可

最后需要 + 1

代码:

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define se second
#define fs first
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define pii pair<int,int>
#define ll long long

int main()
{
    int n, m, k;
    while( scanf( "%d%d%d", &n, &k, &m ) && n + m + k )
    {
        int a = 0;
        for( int i = 2; i <= n; i ++ ) a = ( a + k ) % i;
        m --;
        int b = k - 1;
        b %= n;
        a = ( m - b + a + n ) % n;
        printf( "%d\n", a + 1 );
    }
    return 0;
}
时间: 2024-10-10 10:19:32

UVALive 3882 And Then There Was One的相关文章

UVALive - 3882 —— And Then There Was One

题目:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=11350 约瑟夫环问题 这道题问的是最后死的是那个数字,所以可以不需要模拟,直接通过递推来推出最后幸存的那个数字: 声明:这里我们将所有人的编号都减1.比如8个人的编号变为0~7 我们可以通过倒推的方式获得最后剩下那个人在最开始的编号. 假设,现在只剩最后一个数字,那么我们从它开始编号,那么因为只有它只身一人,所以就只好将它编号为0 那么它在上一轮的编号是多少呢? 通过

UVALive - 3882:And Then There Was One

约瑟夫环 f[i]表示有i个人先处理第k个人,最后被处理的人是谁 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #define MAXN 10005 using namespace std; int f[MAXN]; int n,m,k; int main() { while(1){ scanf("%d%d%d",&n,&k

训练指南DP阶段训练1

最近又忙又颓.............时间抓不紧....下学期开始就要准备考研了.......就2个月左右可以做自己喜欢的事了....争取把紫书和白书没做的,做过的..来一次完整的总结 训练指南上面的5个例题+后面15个习题是第一阶段 vjudge训练地址 http://vjudge.net/contest/139533#overview -------------------------------------------------------------------------------

UVALive 4848 Tour Belt

F - Tour Belt Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVALive 4848 Description Korea has many tourist attractions. One of them is an archipelago (Dadohae in Korean), a cluster of small islands sca

UVALive 6467 Strahler Order 拓扑排序

这题是今天下午BNU SUMMER TRAINING的C题 是队友给的解题思路,用拓扑排序然后就可以了 最后是3A 其中两次RE竟然是因为: scanf("%d",mm); ORZ 以后能用CIN还是CIN吧 QAQ 贴代码了: 1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <math.h> 5 #include <iostre

UVALive 7077 Little Zu Chongzhi&#39;s Triangles (有序序列和三角形的关系)

这个题……我上来就给读错了,我以为最后是一个三角形,一条边可以由多个小棒组成,所以想到了状态压缩各种各样的东西,最后成功了……结果发现样例过不了,三条黑线就在我的脑袋上挂着,改正了以后我发现N非常小,想到了回溯每个棍的分组,最多分5组,结果发现超时了……最大是5^12 =  244,140,625,厉害呢…… 后来想贪心,首先想暴力出所有可能的组合,结果发现替换问题是一个难题……最后T T ,我就断片了.. 等看了别人的办法以后,我才发现我忽视了三角形的特性,和把数据排序以后的特点. 如果数据从

Gym 100299C &amp;&amp; UVaLive 6582 Magical GCD (暴力+数论)

题意:给出一个长度在 100 000 以内的正整数序列,大小不超过 10^ 12.求一个连续子序列,使得在所有的连续子序列中, 它们的GCD值乘以它们的长度最大. 析:暴力枚举右端点,然后在枚举左端点时,我们对gcd相同的只保留一个,那就是左端点最小的那个,只有这样才能保证是最大,然后删掉没用的. UVaLive上的数据有问题,比赛时怎么也交不过,后来去别的oj交就过了. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000&qu

UVALive 6511 Term Project

Term Project Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVALive. Original ID: 651164-bit integer IO format: %lld      Java class name: Main 解题:强连通分量 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1

UVALive 6508 Permutation Graphs

Permutation Graphs Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVALive. Original ID: 650864-bit integer IO format: %lld      Java class name: Main 解题:逆序数 1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long l