Title

每日作业

扣分

有N个会员(编号为1~N)围成一圈, 第一个会员从1开始报数, 报到3的人被拖出去扣分. 下一个接着从1开始报.直到留下最后一位胜利者.

设计一个程序, 输入N, 输出最后的胜利者

 

输入: 整数N,  N(1<=N<=1000)

输出: 胜利者的编号

 

样例输入: 10

样例输出: 4

 

此题可用数学方法求解。


设有n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续bai从0开始报数  (用数学方法解的时候需要注意应当从0开始编号,因为取余会取到0解。)


实质是一个递推,n个人中最终留下来的序号与n-1个人中留下来的人的序号有一个递推关系式。


假设除去第k个人,则


0, 1, 2, 3, ..., k-2, k-1, k, ..., n-1          // 原始序列 (1)


0, 1, 2, 3, ..., k-2,      , k, ..., n-1        // 除去第k人,即除去序号为k-1的人   (2)


k, k+1, ..., n-1,    0,    1,        ..., k-2  // 以序号k为起始,从k开始报0  (3)


0, 1,     ..., n-k-1, n-k, n-k+1, ..., n-2   // 作编号转换,此时队列为n-1人  (4)



换后就完完全全成为了(n-1)个人报数的子问题,注意(1)式和(4)式,是同一个问题,不同的仅仅是人数。比较(4)和(3),不难看
出,0+k=k, 1+k=k+1, ... ,(3)式中'0'后面的数字,((n-3)+k)%n=k-3,((n-2)+k)%n=k-2,
对于(3)式中'0'前面的数字,由于比n小,也可看作(0+k)%n=k,  (1+k)%n=k+1,  故可得出规律:


设(3)中某一数为x' , (4)中对应的数为x,则有:x'=(x+k)%n.


设x为最终留下的人序号时,队列只剩下1人时,显然x=0; 此时可向前回溯至2人时x对应的序号,3人时x对应的序号……直至n人时x的序号,即为所求。

 1 package com.work;
 2 
 3 import java.util.Scanner;
 4 
 5 /**
 6  * @author My
 7  */
 8 public class Assignment_16 {
 9     public static void main(String[] args) {
10         Scanner reading = new Scanner(System.in);
11         System.out.println("输入参赛的人数:");
12         int N = reading.nextInt();
13         System.out.println("选择out的位次:");
14         int S = 0;
15         int n = reading.nextInt();
16         for (int i = 2; i <= N; i++) {
17             S=(S+n)%i;
18         }
19         System.out.print("获胜的是:"+(S+1));
20     }
21 }

 

posted @ 2020-12-14 13:22  WAASSTT  阅读(90)  评论(0)    收藏  举报
Title