看到网上有这样的面试题:
试题:有53个球和一个天平,有一个是空的,问最少要多少次才能找到空心球。最多要多少次,用程序写出来。
算法:三分法,为了保证最佳,采用近三等分方法。每次分三组。如果1、2组相等,肯定在第3组中,否则1、2组中轻的一组中。依次类推,直到找到的一组中剩下一个球时为止。
效果:
Create 53 spheres in random... Hollow sphere is [○07]
[●01][●02][●03][●04][●05][●06][○07][●08][●09][●10][●11][●12][●13][●14][●15][●16][●17][●18][●19][●20][●21][●22][●23][●24][●25][●26][●27][●28][●29][●30][●31][●32][●33][●34][●35][●36][●37][●38][●39][●40][●41][●42][●43][●44][●45][●46][●47][●48][●49][●50][●51][●52][●53]
Find round: 1 in 53 spheres.
into 3 groups:
group 1: [●01][●02][●03][●04][●05][●06][○07][●08][●09][●10][●11][●12][●13][●14][●15][●16][●17]
group 2: [●18][●19][●20][●21][●22][●23][●24][●25][●26][●27][●28][●29][●30][●31][●32][●33][●34]
group 3: [●35][●36][●37][●38][●39][●40][●41][●42][●43][●44][●45][●46][●47][●48][●49][●50][●51][●52][●53]
Find round: 2 in 17 spheres.
into 3 groups:
group 1: [●01][●02][●03][●04][●05]
group 2: [●06][○07][●08][●09][●10]
group 3: [●11][●12][●13][●14][●15][●16][●17]
Find round: 3 in 5 spheres.
into 3 groups:
group 1: [●06]
group 2: [○07]
group 3: [●08][●09][●10]
Find round: 4 in 1 spheres.
The smallest sphere is:[○07]
JAVA代码:
import java.util.Random;
public class FindSmallestSphere {
private static int findRound = 0;
public static Sphere[] initSphere(int max){
System.out.print("Create "+max+" spheres in random...");
Sphere[] s = new Sphere[max];
int idLength = String.valueOf(max).length();
for(int i=0; i<max; i++){
s[i] = new Sphere(formatId(i+1,idLength), Sphere.SOLID_SPHERE_WEIGHT);
}
Random r = new Random();
int hollowIndex =r.nextInt(max);
s[hollowIndex].setWeight(Sphere.HOLLOW_SPHERE_WEIGHT);
System.out.println(" Hollow sphere is " + s[hollowIndex]);
return s;
}
public static String show(Sphere[] spheres, String separator){
StringBuilder sb = new StringBuilder();
for(int i=0; i< spheres.length; i++){
if(i>0)sb.append(separator);
sb.append(spheres[i]);
}
return sb.toString();
}
public static int getSpheresWeight(Sphere[] spheres){
int weight = 0;
for(int i=0; i< spheres.length; i++){
weight += spheres[i].getWeight();
}
return weight;
}
public static Sphere[] subSpheres(Sphere[] spheres, int start, int end){
int max = end-start;
Sphere[] s = new Sphere[max];
for(int i=0; i<max; i++){
s[i] = spheres[start+i];
}
return s;
}
public static void find(Sphere[] spheres){
findRound++;
int total = spheres.length ;
System.out.println("Find round: " + findRound +"/t in " + total + " spheres.");
if( total == 1){
System.out.println("/tThe smallest sphere is:" + spheres[0]);
}else if( total <=3 ){
Sphere s = null;
if(spheres[0].getWeight()<spheres[1].getWeight()){
s = spheres[0];
}else if(spheres[0].getWeight()>spheres[1].getWeight()){
s = spheres[1];
}else{
s = spheres[2];
}
System.out.println("/tThe smallest sphere is:" + s);
}else{
System.out.println("/tinto 3 groups: ");
int gn = total/3;
Sphere[] g1 = subSpheres(spheres,0,gn);
Sphere[] g2 = subSpheres(spheres,gn,gn+gn);
Sphere[] g3 = subSpheres(spheres,gn+gn,total);
System.out.println("/t/tgroup 1: " + show(g1,""));
System.out.println("/t/tgroup 2: " + show(g2,""));
System.out.println("/t/tgroup 3: " + show(g3,""));
if( getSpheresWeight(g1) < getSpheresWeight(g2)){
find(g1);
}else if(getSpheresWeight(g1) == getSpheresWeight(g2)){
find(g3);
}else{
find(g2);
}
}
}
public static void main(String[] args) {
Sphere[] spheres = initSphere(53);
System.out.println(show(spheres,""));
find(spheres);
}
private static String formatId(int id, int length){
StringBuilder sb = new StringBuilder();
String idstr = String.valueOf(id);
int idlength = idstr.length();
for(int i=0; i<length-idlength;i++){
sb.append('0');
}
sb.append(idstr);
return sb.toString();
}
}
class Sphere{
public static final int SOLID_SPHERE_WEIGHT = 80;
public static final int HOLLOW_SPHERE_WEIGHT = 20;
String id;
int weight;
public Sphere(String id, int weight){
this.id = id;
this.weight = weight;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
} public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public String getShow(){
if(this.getWeight()>=SOLID_SPHERE_WEIGHT){
return "●";
}else{
return "○";
}
}
public String toString2(){
StringBuilder sb = new StringBuilder();
sb.append("[id=").append(this.getId()).append(',').append("weight=").append(this.getWeight()).append("]");
return sb.toString();
}
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("[").append(this.getShow()).append(this.getId()).append(']');
return sb.toString();
}
}