• HDU 5860 Death Sequence(死亡序列)


    HDU 5860 Death Sequence(死亡序列)

    Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

     

    Problem Description - 题目描述
    You may heard of the Joseph Problem, the story comes from a Jewish historian living in 1st century. He and his 40 comrade soldiers were trapped in a cave, the exit of which was blocked by Romans. They chose suicide over capture and decided that they would form a circle and start killing themselves using a step of three. Josephus states that by luck or maybe by the hand of God, he and another man remained the last and gave up to the Romans. 
     
    Now the problem is much easier: we have N men stand in a line and labeled from 1 to N, for each round, we choose the first man, the k+1-th one, the 2*k+1-th one and so on, until the end of the line. These poor guys will be kicked out of the line and we will execute them immediately (may be head chop, or just shoot them, whatever), and then we start the next round with the remaining guys. The little difference between the Romans and us is, in our version of story, NO ONE SURVIVES. Your goal is to find out the death sequence of the man. 
     
    For example, we have N = 7 prisoners, and we decided to kill every k=2 people in the line. At the beginning, the line looks like this: 
    1 2 3 4 5 6 7 
    
    after the first round, 1 3 5 7 will be executed, we have
     2 4 6
    
    and then, we will kill 2 6 in the second round. At last 4 will be executed. So, you need to output 1 3 5 7 2 6 4. Easy, right? 
     
    But the output maybe too large, we will give you Q queries, each one contains a number m, you need to tell me the m-th number in the death sequence.
    你可能听说过约瑟夫问题,这个故事来源于公元1世纪的犹太历史学家。他和40位战友被困在一个山洞中,洞口盘踞这罗马人。他们宁死不从,于是围成一个圈,每此经过两个人自杀一人。约瑟夫似乎得“天神眷顾”,和另一人得以苟活,降于罗马人。
    
    现在这个问题更加简单:现有N个从1到N编号的人,每回合选择第1人,第k+1人,第2*k+1人,以此类推直至末尾。这些可怜虫会被即刻揪出行刑(或斩首,或枪毙,或其他),剩余的人则开始下一回合。我们的故事与罗马版略有不同,魔劫千万,生机尽灭。你的任务是找出这些人的死亡序列。
    
    举个例子,现有N = 7个人,我们选择杀死队伍中k=2的人。一开始的队伍如下:
    
    1 2 3 4 5 6 7
    
    第一回合后,1 3 5 7卒,还剩
    
    2 4 6
    
    随后,我们在第二回合杀死2 6。4最后死。因此你需要输出1 3 5 7 2 6 4。简单否?
    
    然而这样输出太长了,我们会给你Q个询问,每个询问有一个数字m,你需要输出死亡序列第m个数。
    CN
    Input - 输入
    Multiple cases. The first line contains a number T, means the number of test case.
    For every case, there will be three integers N (1<=N<=3000000), K(1<=K), and Q(1<=Q<=1000000), which indicate the number of prisoners, the step length of killing, and the number of query.
    Next Q lines, each line contains one number m(1<=m<=n).
    多组用例。第一行为一个整数T,表示测试用例的数量。
    对于每个测试用例,有三个整数N (1<=N<=3000000),K(1<=K),和Q(1<=Q<=1000000),分别表示囚徒的数量,死亡间隔数,还有询问的数量。
    随后N行,每行有一个整数m(1<=m<=n)。
    CN

    Output - 输出
    For each query m, output the m-th number in the death sequence.
    对于每个询问m,输出死亡序列中第m个数。
    CN

    Sample Input - 输入样例

    1
    7 2 7
    1
    2
    3
    4
    5
    6
    7
    

    Sample Output - 输出样例

    1
    3
    5
    7
    2
    6
    4
    

     

    题解

      动态规划。
      为了取模方便,可以从0开始。
      用turn[i]表示,表示当前位置可以存活多少轮,利用下一轮中的位置比本轮中的位置多苟活1s,可以用得到当前的苟活数。
      即:turn[i] = i%k ? turn[i - i / k - 1] + 1 : 0
      还能再用一个数组sum算出每回合死亡的人生,为了最后的输出做准备。

     

    代码 C++

     1 #include <cstdio>
     2 #define  mx 3000005
     3 int turn[mx], sum[mx], opt[mx];
     4 int main(){
     5     int t, n, k, q, m, i, j;
     6     for (scanf("%d", &t); t; --t){
     7         scanf("%d%d%d", &n, &k, &q);
     8         sum[0] = 0;
     9         for (j = n, i = 1; j; ++i){
    10             sum[i] = j / k;
    11             if (j%k) ++sum[i];
    12             j -= sum[i];
    13             sum[i] += sum[i - 1];
    14         }
    15         for (i = 0; i < n; ++i){
    16             turn[i] = i%k ? turn[i - i / k - 1] + 1 : 0;
    17             opt[++sum[turn[i]]] = i + 1;
    18         }
    19         for (i = 0; i < q; ++i){
    20             scanf("%d", &m);
    21             printf("%d
    ", opt[m]);
    22         }
    23     }
    24     return 0;
    25 }
  • 相关阅读:
    C++ 遇到的问题小结
    学习笔记之 初试Caffe,Matlab接口提取feature
    学习笔记之 初试Linux遇到的问题 2015-10-13
    函数式编程
    如何获取select中的value、text、index相关值 && 如何获取单选框中radio值 && 触发事件 && radio 默认选中
    sessionStorage、localStorage技术相关以及商家sid、sbid记录相关、vue相关问题
    二进制数的妙用
    vue中的坑 --- 锚点与查询字符串
    vue-webpack项目中调试的问题
    JSON中的坑
  • 原文地址:https://www.cnblogs.com/Simon-X/p/6011895.html
Copyright © 2020-2023  润新知