这是一个约瑟夫环的问题
创新互联建站凭借专业的设计团队扎实的技术支持、优质高效的服务意识和丰厚的资源优势,提供专业的网站策划、成都网站建设、做网站、网站优化、软件开发、网站改版等服务,在成都十年的网站建设设计经验,为成都上1000+中小型企业策划设计了网站。
解答如下:
依据提议,可以将题目等价变换为:“n(n=17)人编号为0到(n-1)围成一圈,0号人开始从0报数,凡是报数为m-1 (m=3)倍数的人离开圈子,继续到一个,问他编号”
一开始的状态
0,1,2,3,4,5 ..... (n-2), (n-1) 【n个人】
第一个人被踢之后 设第一个被踢的人的编号为k, 则 k = m%n-1 【当n=17,m=3时,k=2。也就是说编号为2的人离开了圈子】
这时候的状态
0, .... (k-1), (k+1) ,(k+2)...(n-2),(n-1) 【(n-1)个人,当n=17,m=3时: 0,1,3,4,5,6,7,8,9,10,11,12,13,14,15,16】
将这时候的编号做转换. 因为是围城一个圈子,下一个开始数的是(k+1).所以也可以表示为
(k+1),(k+2) ... (n-2),(n-1),0....(k-1) 【(n-1)个人,当n=17,m=3时: 3,4,5,6,7,8,9,10,11,12,13,14,15,16,0,1】
重新编号。得到:
0,1,2,3,4...(n-3),(n-2)【(n-1)个人】 这个时候 ,这里重新构成了一个约瑟夫环。也就是说,这是一个递推的关系。
这里我们进行了重新编号。那么 (n-1)个人和 n个人之间的编号不一样的。但是两者之间有一定的关系,可以冲新编号推导出老的
公式如下: i' = (i+k)%(n-1) 【比如,当n=17,m=3时 . 新的环编号是 (n-2),我要求他在老的环中的编号,那么编号是 i' = ( (n-2) + k ) % (n-1) = 17%16 = 1,就是老的换种编号为1的那一个 】
反过来有 :i = (i'+m)%n
有了上面的推断,可以代码如下:
int ysf(int n,int m){
if(n==1){
return 0; //当环内只有一个人的时候,就是他自己
}
return (ysf(n-1,m) + m ) % n ;
}
------------------完整代码---------------------
public class Test{
public static void main(String[] args){
int a = 17;
int b = 3;
System.out.println(ysf(a,b));
}
static int ysf(int n,int m){
if(n==1){
return 0;
}
return (ysf(n-1,m) +m) % n;
}
}
是这个吗?
/**[12,127,85,66,27,34,15,344,156,344,29,47,....]
这是某设备测量到的工程数据。
因工程要求,需要找出最大的5个值。
一般的想法是对它排序,输出前5个。但当数据较多时,这样做很浪费时间。因为对输出数据以外的数据进行排序并非工程要求,即便是要输出的5个数字,也并不要求按大小顺序,只要找到5个就可以。
以下的代码采用了另外的思路。考虑如果手里已经抓着5个最大数,再来一个数据怎么办呢?让它和手里的数据比,如果比哪个大,就抢占它的座位,让那个被挤出来的再自己找位子,....
* **/
import java.util.*;
public class B23{
public static ListInteger max5(ListInteger lst){
if(lst.size()=5) return lst;
int a = lst.remove(lst.size() - 1); // 填空
//System.out.println(a);
ListInteger b = max5(lst);
for(int i=0; ib.size(); i++)
{
int t = b.get(i);
if(at)
{
lst.set(i, a); // 填空
a = t;
}
}
return b;
}
public static void main(String[] args){
ListInteger lst = new VectorInteger();
lst.addAll(Arrays.asList(12,127,85,66,27,34,15,344,156,344,29,47));
System.out.println(max5(lst));
}
}
import java.util.Scanner;public class Test {public static void main(String[] args) {int num = 5;int[] n = new int[num];Scanner sc = new Scanner(System.in);System.out.println("请输入"+num+"位会员的积分");for(int i=0;inum;i++){System.out.print("第"+(i+1)+"位会员积分:");n[i]=sc.nextInt();}System.out.println("\n序号\t历史积分");for(int i=0;in.length;i++){System.out.println(i+1+"\t"+n[i]);}sc.close();}}
//递归
private static double wages1(int n)
{
if (n = 0)
{
return 0;
}
else if (n == 1)
{
return 1500*12;
}
else
{
return wages1(n-1) * 1.1;
}
}
//递推
private static double wages2(int n)
{
if (n = 0)
{
return 0;
}
double wages = 1500 * 12;
for (int i = 1; i n ; i++)
{
wages *= 1.1;
}
return wages;
}
递归是吧,这样就可以了 #include "stdio.h" static int k=0; void F(int a) { if (a==1) return ; k++; if(a%2==1) a=a*3+1; else a=a/2; printf("%d\n",a); F(a); } void main() { int a=0; printf("input your number\n"); scanf("%d",a); F(a); printf("the function totally calculated %d times",k); }
int a=0;
int n=0;
String s ;
try{
System.out.print("请输入一个整数n:");
BufferedReader br=
new BufferedReader(new InputStreamReader(System.in));
s=br.readLine();
a=Integer.parseInt(s);
} catch(IOException e){}
以上代码请放在main函数里面。