N个数字模K问题

问题描述:n 个数字(0,1,…,n-1)形成一个圆圈,从数字0 开始, 每次从这个圆圈中删除第K 个数字(第一个为当前数字本身,第二个为当前数字的下一个
数字)。
当一个数字删除后,从被删除数字的下一个继续删除第K 个数字。
求出在这个圆圈中剩下的最后一个数字m

术语定义:n是最开始的数字总数m是圆圈中的最后一个数字p(i)第i次删除数字之后,还剩余的数字个数,p(1)=n-1,p(n-1)=1,0=<i<=n-1;

我们可以对p(i)进行编号,0....p(i)-1,下标为0开始的地方就是第i次被删除的数字的下一个数字开始。

例如n=5,k=3,i=0;时p(0)=5

编号:0 1 2 3 4
数值:0 1 2 3 4

i=1时p(1)=4

编号:0 1 2 3
数值:3 4 0 1

i=2时p(2)=3

编号:0 1 2
数值:1 3 4

 

i=3时p(3)=2

编号:0 1
数值:1 3

i=4时p(4)=1

编号:0 
数值:3 

思路:对于这种问题最好先模拟几次,寻找规律。要么是自顶向下N个数字每次减少一个数字,直到最后一个数字;要么是从最后一个数字开始,慢慢恢复到最后一个数字m在N的位置。

采用自底向上的思路考虑,对于n=1,无论k是多少,m就是0;

假设n=2,那么p(0)=2,p(1)=1,最后一轮下标为0的数值,就是m,那么最后一轮的下标,对应上一轮的下标是多少?

示例:

n=2,k=3

p(0)=2

编号:0 1
数值:0 1

p(1)=2

编号:0 
数值:1 

可见对于对于最后一轮时,计算出m=1,它对应的编号为0,但是它对应的上一轮编号为1,找出编号的对应关系就可以找到最后一个数字m。

也就是说我们要求的对应关系是,经过i次删除数据之后,假设第i次删除数据的下标为j,那么j所指向的值,在第i-1的下标是多少

第i次删除数据时,指向的下标为K%P(i-1),第i次下标为0的值value,与该value在p(i-1)的关系是什么?p(i-1)中的第(K+1)%(n-1)对应的就是第i次

的0。

由此我们可以从p(n-1)次下标为0的位置推出对应的p(n-2)对应的位置依次类推,就可以推出m在p(0)中的相应位置。

附上代码。

package nAndK;

import java.util.Scanner;

public class NAndK {
private static Scanner  myscanner;
public static void loopset()
{
    myscanner=new Scanner(System.in);
    boolean goon=true;
    while(goon)
    {
        System.out.println("请输入n和k");
        System.out.print("n=");
        int n=myscanner.nextInt();
        System.out.print("k=");
        int k=myscanner.nextInt();
        int m=0;
        for(int i=2;i<=n;i++)
        {
            m=(m+k)%i;
        }
        System.out.println("("+n+","+k+","+m+")");
    }
}
public static void main(String[] args) 
{
    loopset();
}
}

PS:假设:不是n 个数字(0,1,…,n-1)形成一个圆圈,是从(1,2,...,n)围成一个圈时,模运算的方便,可以仍然按照(0,1,…,n-1)开始计算,
最后返回M+1即可。
    

                                                    菜包子

                                                    2013年5月15日19:15:23

                                                于马甸桥东

 

 

 

 

 

 

 

 

posted on 2013-05-15 19:16  菜包子  阅读(265)  评论(0编辑  收藏  举报

导航