Algs4-1.4.34A热还是冷-2lgN

1.4.34热还是冷。你的目标是猜出1到N之间的一个秘密的整数。每次猜完一个整数后,你会知道你的猜测和这个秘密整数是比较热(接近)还是比较冷(远离)。设计一个算法在~2lgN之内找到这个秘密整数,然后再设计一个算法在~1lgN之内找到这个秘密整数。
答:
1)猜1
2)猜N
3)
3.1)如果秘密数是1,猜中。
3.2) 如果秘密数是N,猜中。
3.3) 如果秘密数不是1,也不是N时如果猜N相对猜1时变热说明秘密数在N/2+1至N-1中,那么接着猜N/2、N,也可考虑猜N/2+1、N-1。
3.4)不变热时说明秘密数在2至N/2中,那么接着猜1、N/2,也可考虑猜2、N/2。
         按上述过程反复执行,直到猜到为止。(由于秘密数一定是在1至N中,所以一定能猜中。)
         注:由于每次猜测只能知道相对上一次猜测是变冷或变热,如果先猜小数,后猜大数,秘密数离小数近时,猜中间数一定是变热,所以每次迭代都不得不猜两个数。也就是~2lgN次。
图片
public class E1d4d34A
{
  public static void main(String[] args)
  {
    int N=Integer.parseInt(args[0]);
    int key=Integer.parseInt(args[1]);
    StdOut.printf("N=%d,key=%d,guesskey=%d",N,key,guessKey(N,key));
  }//end main
 
  public static int guessKey(int N,int key)
  {
    int guess1=1;
    int guess2=N;
    int guessResult;
    while (true)
    {
      guessResult=guessTwoNumber(guess1,guess2,key);
      StdOut.printf("guess1=%d,guess2=%d ",guess1,guess2);
      if (guessResult==1)//guess1 is key
        return guess1;
      else if (guessResult==2)//guess2 is key
        return guess2;
      else if (guessResult==3)//hot
        guess1=(guess1+guess2)/2;
      else//cold
        guess2=(guess1+guess2)/2;
    }//end while
 }//end guessKey
 
  public static int guessTwoNumber(int guess1,int guess2,int key)
  {
    if (guess1==key)
      return 1;// "guess1"
    else if(guess2==key)
      return 2;//"guess2"
    else if(Math.abs(guess1-key) >Math.abs(guess2-key))
      return 3;// "hot";
    else
      return 4;// "cold"
  }

}//end class

原文地址:https://www.cnblogs.com/longjin2018/p/9854514.html