图片发自简书App
注:图片来源于网络
老板:各位朋友们,瞧。。。这里有一堆金币(已知数量),但是里面有一枚是假币,质量比真金币要轻,谁能把这枚金币找出来,这些金币都作为你的奖励。。。
程序员:哈哈,即将走上人生巅峰~迎娶白富美。。。
注:梦里什么都有
于是,随手拿起笔记本电脑开始敲代码。。。
这就是经典的算法题—寻找假币算法
我们的解题思路是这样的:
第一步:先判断金币总数的奇偶性
第二步:如果是奇数,抽取一枚金币
第三步:将金币分成数量相同的两部分
第四步:比较两部分的质量,取质量小的那部分。在金币总数为奇数情况下,如果质量相同,那么取出的那枚金币就是假币
第五步:舍弃质量大的部分,取第四步中质量小的那部分,重复步骤3-4(偶数不断均分依然是偶数),直到最后剩下两枚金币。‘
先上图
’再上代码(如果格式混乱请放在IDE中用格式化快捷键):
import java.util.Scanner;
public class falseTeaat {
public static void main(String[] args) {
int n;
Scanner input =new Scanner(System.in);
System.out.println(“请输入硬币总个数”);
n=input.nextInt();
int [] coin=new int[n];
int i;
int weizhi;
System.out.println(“请给硬币输入重量(真硬币重量要相同,假硬币重量必须小于真硬币重量”);
for(i=0;i<n;i++) {
coin[i]=input.nextInt();
}
weizhi=FalseCoin(0,n-1,coin);
System.out.println(“假币位置在”+weizhi);
input.close();
}
static int FalseCoin(int low,int high,int coin[]) {
int i,weightSum1,weightSum2;//weightSum1用于存放被分成两堆的硬币的前一半的总重量 weightSum2用于存放后一半的总重量
int re=0;
weightSum1=weightSum2=0;
if(low+1==high) {//剩下两枚的情况 也相当于递归见到了”曙光”。。。
if(coin[low]<coin[high]) {
return low+1;
}
else {
return high+1;
}
}
//偶数的情况
if((high-low+1)%2==0){//因为数组下标从0开始,如果是偶数枚,则high-low必定是奇数,需要加1
for(i=low;i<=(low+high)/2;i++) {
weightSum1+=coin[i];//计算前半部分重量和
}
for(i=(low+high)/2+1;i<=high;i++) {
weightSum2+=coin[i];//计算后半部分重量和
}
if(weightSum1>weightSum2) {
return FalseCoin((low+high)/2+1,high,coin);
}
else{
return FalseCoin(low,(low+high)/2,coin);
}
}
//奇数的情况
else {
//注意这里的两个for循环中第一个for循环的判断条件 还有第二个for循环的起始条件。
//这里留下了(low+high)/2 ,也相当于取出编号在最中间的那枚。
for(i=low;i<=(low+high)/2-1;i++) {
weightSum1+=coin[i];
}
for(i=(low+high)/2+1;i<=high;i++) {
weightSum2+=coin[i];
}
if(weightSum1>weightSum2) {
return FalseCoin((low+high)/2+1,high,coin);
}
else if(weightSum1<weightSum2) {
return FalseCoin(low,(low+high)/2-1,coin);
}
if(weightSum1==weightSum2) {
return (low+high)/2+1; //这里加1是因为数组下标从0开始,而通常我们是从1开始数的。
}
}
return re;
}
}
//如果有什么建议,欢迎指出。谢谢啦。