hdu 2211:杀人游戏(递归)

2023-10-17 23:10
文章标签 游戏 递归 hdu 杀人 2211

本文主要是介绍hdu 2211:杀人游戏(递归),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

hdu 2211:杀人游戏(递归)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2211


Problem Description


不知道你是否玩过杀人游戏,这里的杀人游戏可没有法官,警察之类的人,只有土匪,现在已知有N个土匪站在一排,每个土匪都有一个编号,从1到N,每次杀人时给定一个K值,从还活着的土匪中,编号从小到大的找到K个人,然后杀掉,继续往下,直到找遍,然后继续从剩下的土匪中,编号从小到大找到第K个活着的土匪,然后杀掉。比如,现在有10个土匪,K为3,第一次杀掉3,6,9号的土匪,第二次杀掉4,8号土匪,第三次杀掉5号土匪,第四次杀掉7号土匪,第五次杀掉10号土匪,我们看到10号土匪是最后一个被杀掉的(从1到K-1的土匪运气好,不会被杀!)。现在给定你一个N和一个K,问你最后一个被杀掉的土匪的编号是多少。


Input


第一行有一个T(T<=10000),接下来有T组数据,每组中包含一个N(N<2^31)和一个K(3<=K<=100&&K<N)。


Output


对于每组数据,输出最后被杀的土匪的编号。


Sample Input


1
10 3


Sample Output


10

又是一道烧脑题,这种题谁受得了啊,找不到突破口寸步难行,找到了水的要死。。。。

以下题解参考这位博主的博客:传送门

★先说递归思想:递推关系+边界条件,二者缺一不可。这道题的递推关系是根据前一轮胜利者的编号确定当前轮胜利者的编号,一直递推下去到最后一轮(也就是边界条件),胜利者在1,2,3,……,k-1,k的第k个位置上。即n==k时,返回k.

★再说整除方程(返回值的确定)。

如果你查阅相关结题报告,凡是递归解决的无外乎这样一段话:
在这里插入图片描述

这句话只是结论呦,推导看我的吧~

设上一轮胜利者的编号为x,当前轮胜利者的编号为y,容易推到得到这样的一个方程:y=y/k+x
式子意义是当前编号=这一轮在y之前被杀死的数量+上一轮在y之前剩下的数量x
注意,这可不是一般的方程哦,/表示的是整除,不要左右同×k,结果不等价的。
这样的方程笔者姑且叫她整除方程吧,利用不等式求解。求解思路如下:
●Step1 首先观察到y无法直接求解,不妨先求y/k,设m=y/k,则y=m+x(x已知),问题转化为求整除结果m.
●Step2 由y/k=m有,m·k+1<=y<=m·k+(k-1).为什么是m·k+1<=y而不是m·k<=y,因为y表示的是当前这轮胜利者的编号,不到最后一轮不会出现y%k==0的情况(最后一轮已经被返回了)。令y=m+x,代入得到
m·k+1<=m+x<=m·k+(k-1),原不等式组等价于

m·(k-1)<=x-1<=m·(k-1)+(k-2).

看出来没有??!!!把她反一下就可以表示为m=(x-1)/(k-1),两者表示的含义是不是等价的????!!!!Yes!!
那么m就求出来啦.则y=y/k+x=m+x=(x-1)/(k-1)+x 了,参考递归代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
/**递归函数*/
int fx(int n,int k)
{if(n==k)       //递归条件return k;int x=fx(n-n/k,k);     //胜利者在下一个子序列的编号记为:xreturn (x-1)/(k-1)+x;        //那么这一轮编号为y=y/k+x;
}
int main()
{int t;int n,k;      //即:题目所说的土匪总数,以及每次所杀的区间scanf("%d",&t);while(t--){scanf("%d%d",&n,&k);int num;/**调用函数*/num=fx(n,k);printf("%d\n",num);}return 0;
}

这篇关于hdu 2211:杀人游戏(递归)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/228577

相关文章

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

hdu 2093 考试排名(sscanf)

模拟题。 直接从教程里拉解析。 因为表格里的数据格式不统一。有时候有"()",有时候又没有。而它也不会给我们提示。 这种情况下,就只能它它们统一看作字符串来处理了。现在就请出我们的主角sscanf()! sscanf 语法: #include int sscanf( const char *buffer, const char *format, ... ); 函数sscanf()和

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

hdu 3790 (单源最短路dijkstra)

题意: 每条边都有长度d 和花费p,给你起点s 终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。 解析: 考察对dijkstra的理解。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstrin

hdu 2489 (dfs枚举 + prim)

题意: 对于一棵顶点和边都有权值的树,使用下面的等式来计算Ratio 给定一个n 个顶点的完全图及它所有顶点和边的权值,找到一个该图含有m 个顶点的子图,并且让这个子图的Ratio 值在所有m 个顶点的树中最小。 解析: 因为数据量不大,先用dfs枚举搭配出m个子节点,算出点和,然后套个prim算出边和,每次比较大小即可。 dfs没有写好,A的老泪纵横。 错在把index在d

hdu 1102 uva 10397(最小生成树prim)

hdu 1102: 题意: 给一个邻接矩阵,给一些村庄间已经修的路,问最小生成树。 解析: 把已经修的路的权值改为0,套个prim()。 注意prim 最外层循坏为n-1。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstri

hdu 1285(拓扑排序)

题意: 给各个队间的胜负关系,让排名次,名词相同按从小到大排。 解析: 拓扑排序是应用于有向无回路图(Direct Acyclic Graph,简称DAG)上的一种排序方式,对一个有向无回路图进行拓扑排序后,所有的顶点形成一个序列,对所有边(u,v),满足u 在v 的前面。该序列说明了顶点表示的事件或状态发生的整体顺序。比较经典的是在工程活动上,某些工程完成后,另一些工程才能继续,此时