这篇文章我们来谈谈分治算法,分治算法也就是将大的问题分解成为小的问题,然后依次求解,如果在一堆硬币里有1个假的硬币,那么我们可以堆硬币为偶数那么分成两堆,然后再质量小的那堆里面求解,如果硬币的个数为奇数,那么我们以中间的为分割,如果两堆相等,那么中间的就是假的,否则就和偶数的求解思路是一样的,然后依次算下去,直到找到假币为止,好吧,贴代码:
package www.jk.divideandconquer;
import java.util.Scanner;
/**
* 用户可以输入硬币的个数,然后动态输入硬币的质量,只能有一个假币,假币的质量小于真币,然后求出假币的位置
*
* @author jk
*
*/
public class Test {
public static void main(String[] args) {
int[] coin = new int[1000];
int number;
int position;
System.out.println("输入硬币的数目");
Scanner input = new Scanner(System.in);
number = input.nextInt();
System.out.println("请输入硬币的真假");
for (int i = 0; i < number; i++) {
// 得到硬币的质量
// get the quality of the coin
coin[i] = input.nextInt();
}
// get the position of the false coin
// 得到假的硬币的位置
position = falseCoin(coin, 0, number - 1);
System.out.println("第" + position + "个硬币是假的");
}
public static int falseCoin(int[] coin, int low, int high) {
int res = 0;
int i, sum1, sum2, sum3;
sum1 = sum2 = sum3 = 0;
// if there were only two coin ,the quality of small is false,we need to
// add 1,because the
// value we passed in is array subscript
// 如果只有两个硬币,那么质量小的就是假的,因为是我们传入的是数组的下标,所以位置要加1
if (low + 1 == high) {
if (coin[low] < coin[high]) {
res = low + 1;
} else {
res = high + 1;
}
return res;
}
// if the total number is an even number, then high sub low will get a
// odd number
// the number divide 2 is the offset that we want
// 如果是偶数,想想一下只有两个数,那么high-low得到的是一个奇数,而除以2的结果正好是我们需要的偏移量
if ((high - low + 1) % 2 == 0) {
// the sum of firt half
// 前半段的和
for (i = low; i <= low + (high - low) / 2; i++) {
sum1 += coin[i];
}
// the sum of last half
// 后半段的和
for (i = low + (high - low) / 2 + 1; i <= high; i++) {
sum2 += coin[i];
}
// if the sum1>sum2,the false coin is in the rear
// 如果前面大,那么假币在后面
if (sum1 > sum2) {
res = falseCoin(coin, low + (high - low) / 2, high);
} else {
// else the false coin is in the begin
// 否则的话,假币在前面
res = falseCoin(coin, low, low + (high - low) / 2);
}
// return the result
// 返回得到的结果
return res;
} else {
// if the number is odd, we can image that the total number is
// threee ,and high-low will get a evev number
// this number will bigger one than the offset that we need
// 如果是奇数,我们可以想象为3,那么high-low得到的是一个偶数,而除以2以后得到的数
// 比我们需要的偏移量多1个,那么我们前半段需要减1,后半段需要加1
// the sum of begin half
// 前半段的和
for (i = low; i <= low + (high - low) / 2 - 1; i++) {
sum1 += coin[i];
}
// the sum of end hald
// 后半段的和
for (i = low + (high - low) / 2 + 1; i <= high; i++) {
sum2 += coin[i];
}
// if sum1 is bigger ,the false coin is in the rear
// 如果前半段大,那么假币在后半段
if (sum1 > sum2) {
res = falseCoin(coin, low + (high - low) / 2, high);
} else if (sum2 > sum1) {
// if sum2 is bigger, the false coin is in the begin
// 如果后半段大,那么假币在前半段
res = falseCoin(coin, low, low + (high - low) / 2);
} else {
// then the result is in the middle
// 否则结果就在中间
res = low + (high - low) / 2 + 1;
}
return res;
}
}
}