看到一个翻硬币题目,想了半天,不得其解,遂搜之...
发现这个博文写了几种思路,惊叹此人算法如此之好!
此处把几种思路以Java实现,特此记录...
http://blog.youkuaiyun.com/jia_xiaoxin/archive/2008/08/30/2852389.aspx
题目:
一摞硬币共有m枚,每一枚都是正面朝上。取
下最上面的一枚硬币,将它翻面后放回原处。然后取下最上面的2枚硬币,将他们一起翻面后再放回原处。再取3枚,取4枚……直至m枚。然后再从这摞硬币最上
面的一枚开始,重复刚才的做法。这样一直做下去,直到这摞硬币中的每一枚又都是正面朝上为止。例如,m为1时,翻两次即可。m为2时,翻3次即可;m为3
时,翻9次即可;m为4时,翻11次即可;m为5时,翻24次即可;…;m为30时,翻899次即可;…
输 入:
仅有的一个数
字
是这摞硬币的枚数m,0<m<1000。
输 出:
为了使这摞硬币中的每一枚又都是正面朝上所必
需翻的次数。
某单
元
格
输入:
30
某单元格等于:
899
思路:不管硬币的次序,只是记住每次的翻转和交换,硬币的初 始状态都是TRUE,每个COIN经过多伦的翻转后都变回TRUE,那么就求出了解,这是最简单的思路。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class TurnCoin {
public static void turn(int m){
int turnTimes = 0;
boolean flag = false;
boolean[] coins = new boolean[m];
for(int i=0;i<m;i++){
coins[i] = true;
}
while(!flag){
for(int i=0;i<m;i++){
for(int j=0;j<(i+1)/2;j++){
boolean temp = coins[j];
coins[j] = !coins[i-j];
coins[i-j] = !temp;
}
if((i+1)%2 == 1){
coins[i/2] = !coins[i/2];
}
turnTimes = turnTimes + 1;
flag = true;
for(int n=0;n<m;n++){
if(coins[n] == false){
flag = false;
break;
}
}
if(flag){
break;
}
}
}
System.out.println(turnTimes);
}
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
turn(n);
}
}
待继....