个人理解二分治算法
import java.util.Scanner;
//coin[] 代表输入的所有银币 0,起始位置 n-1 索引
//分治算法
//主要利用数学中的对折法 递归
//对折到还有两个数为止
//类似于递归
// 思路: 10球每个球重量为一克,其中有一个为2克
// 平均分成两组 每五个一组(A B)
//
//A>B 证明在A组 A组继续分成两组A1 A2 还有A3(代表中间的 自己独自成一组) 在比较A1和A2的大小 分三种情况 A1>A2 A1<A2 A1=A2(相等时候A3就为想找的球)
//A<B 证明在B组 B组继续分成两组B1 B2 类似于(A>B) 层层循环条用最后得出结果
//A1
//
public class P3_4 {
static final int MAXNUM = 6;
static int FalseCoin(int coin[],int low,int high){
int i,sum1,sum2,sum3;
int re = 0;
sum1 = sum2 = sum3 = 0;
//传入两个银币时候(对折到最后)
if(low + 1 == high){
if(coin[low]<coin[high]){
return low + 1;
}
else{
return high +1;
}
}
//
if((high-low +1)%2 == 0){ // n是偶数
for(i = low;i<= low+(high-low)/2;i++){
sum1 = sum1 + coin[i]; //前半段和
}
for(i = low+(high-low)/2+1;i<=high;i++){
sum2 = sum2 + coin[i]; //后半段求和
}
if(sum1 > sum2){
// high 5 low 3 执行不为偶数的
return FalseCoin(coin,low+(high-low)/2+1,high);
}
else if(sum1 < sum2){
return FalseCoin(coin,low,low+(high-low)/2);
}else{
}
}else{ //n是奇数时
for(i = low;i<=low+(high-low)/2-1;i++){
sum1 = sum1 + coin[i]; //前半段和
}
for(i = low + (high-low)/2+1;i<=high;i++){
sum2 = sum2 + coin[i]; //后半段求和
}
sum3 = coin[low+(high-low)/2]; //代表中间的(独立于sum1 和sum2)
if(sum1 >sum2){
return FalseCoin(coin,low+(high-low)/2+1,high);
}
else if(sum1<sum2){
return FalseCoin(coin,low,low+(high-low)/2-1);
}else{
}
if(sum1+sum3 == sum2 +sum3){
return low +(high -low)/2+1;
}
}
return re;
}
public static void main(String[] args) {
int[] coin = new int[MAXNUM];
int i,n;
int weizhi;
System.out.println("分治算法求解假银币问题");
System.out.println("请输入银币总的个数");
Scanner input = new Scanner(System.in);
n = input.nextInt(); //银币总个数
System.out.println("请输入银币的真假");
for(i = 0;i<n;i++){
coin[i] = input.nextInt(); //输入银币真假
}
weizhi = FalseCoin(coin,0,n-1);
System.out.println("第"+weizhi+"是假币");
}
}