John Gilder在等车的时候拿出一摞硬币。首先这些硬币全部正面朝上,第一次翻转最上面的一个,第二次把最上面的两个一起翻转,第三次把最上面的三个硬币一起翻转,...,第n次一起翻转所有的n个硬币,第n+1次再将第一个硬币翻转,...,第m次将最上面m%n个硬币一起翻转。他发现,经过有限次的翻转后,硬币还能恢复到全部正面朝上。请编程验证这个过程。
图:四个硬币的翻转过程
输入:
初始硬币的数量n
输出:
至少需要多少次翻转,又能恢复最初的正面朝上。
样例输入:
4↵
样例输出:
11↵
import java.util.Scanner;
public class Main {
/**
* 反转硬币
*/
public static void main(String[] args) throws Exception {
Scanner cin = new Scanner(System.in);
//定义输入硬币数据
int coinNum = cin.nextInt();
playCoin(coinNum);
}
private static void playCoin(int coinNum){
//判断硬币数量,如果小于1,结束程序
if(coinNum<1){
System.out.println("没有硬币");
return;
}
//定义布尔数组,跟踪硬币正反面
boolean[] flag = new boolean[coinNum];
//true为正面,false为反面
for(int i=0;i<coinNum;i++){
//初始所有硬币为正面的啊
flag[i]=true;
}
//定义反转次数
int count = 0;
//定义反转真假
boolean t = true;
//处理反转硬币正反情况BEGIN
while(t){
int loop = count%coinNum;
if(loop==0){
flag[0]=!flag[0];
}else{
for(int j=0;j<=loop/2;j++){
boolean coin = flag[j];
flag[j]=flag[loop-j];
flag[loop-j]=coin;
}
for(int j=0;j<=loop;j++){
flag[0]=!flag[0];
}
}
//记录反转次数
count++;
t=false;
//判断硬币是否都为正面,如果是则退出循环输出反转数
for(int n=0;n<coinNum;n++){
if(!flag[n]){
t=true;
break;
}
}
}
//处理反转硬币正反情况END
//输出硬币反转次数
System.out.println(count);
}
}