算法学习【1】三个空汽水瓶可以换一瓶汽水

       开始在牛客网上刷题,遇到的第一题是“换汽水”问题:

       有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝?


       本文只讨论JAVA语言解决该问题的程序。

       三个空汽水瓶可以换一瓶汽水,但是又产生了一个空汽水瓶。两个空汽水瓶可以借一瓶换一瓶汽水然后将产生的一个空汽水瓶还回,等于说两个空汽水瓶可以换一瓶汽水,并且不产生空汽水瓶

       因此,可以得出空汽水瓶数num1与喝到的饮料数num2的关系:

num1=奇数,num2=(num1-1)/2,手里剩余1个空汽水瓶

num1=偶数,num2=num1/2,    手里剩余0个空汽水瓶

       也可以认为,将最开始手里的空汽水瓶数分成2个1组,每组换一瓶汽水,最后剩余0或1个空汽水瓶。


       由于机试时间较短,一般做法是写出几组数据,直接找出规律编程。以题目给出的输入例子为例:

       初始:    num1=3,num2=0;

       换一次:num1/3=1,num1=num1/3+num1%3=1,num2=num2+num1/3=0+1=1;

       初始:    num1=10,num2=0;

       换一次:num1/3=3,num1=num1/3+num1%3=4,num2=num2+num1/3=0+3=3;

       换二次:num1/3=1,num1=num1/3+num1%3=2,num2=num2+num1/3=3+1=4;

       换三次:num1/3=0,num1=num1/3+num1%3=2,num2=num2+num1/3=4+1=5;

       从10->4->1的过程,可以得出其实是一个递归的过程,递归公式为:a(n+1)=a(n)/3+a(n)%3,终止条件是手里的空汽水瓶数num1小于3,num1=1直接返回,num1=2时num2++返回。程序如下:

import java.util.Scanner
public class MyCode3{
	static int num2=0;//喝道的饮料数

	public static void main(String[] args){
		int[] num1 = new int[10];//空瓶子数
		int count = 0, temp;
		Scanner sc = new Scanner(System.in);
		while(count<10){
			temp = sc.nextInt();
			if(temp==0)	break;
			num1[count] = temp;
			count++;
		}

		for(int i=0;i<count;i++){
			num2 = 0;
			fun(num1[i]);
			System.out.println(num2);
		}
	}

	public static void fun(int n){
		if(n==1){
			return;
		}if(n==2){
			num2++;
			return;
		}else if(n>=3){
			num2 = num2+n/3;
			fun(n/3+n%3);
		}
	}
}

       有时候机试较紧张,一时无法找出递归规律,或者递归函数编程不熟悉,则可以考虑用循环。程序模拟换水瓶过程,从一堆空汽水瓶里一个一个往外拿,积累到三个就换一次,最后空汽水瓶剩2个也换一个然后结束,空汽水瓶剩0或1个也结束

import java.util.Scanner;
public class MyCode4{
	public static void main(String[] args){
		int[] num1=new int[10];
		int count=0, temp;
		Scanner sc = new Scanner(System.in);

		while(count<10){
			temp = sc.nextInt();
			if(temp==0)	break;
			num1[count] = temp;
			count++;
		}

		int num2, n;
		for(int i=0;i<count;i++){
			num2=0;
			n=0;

			while(num1[i]>=2){
				if(num1[i]==2){
					num2++;
					num1[i]=0;
				}else if(n==3){
					num2++;
					num1[i]=num1[i]-3+1;
					n=0;
				}
				n++;
			}

			System.out.println(num2);
		}
	}
}

       

       可见,这道题的核心是递归,因此把递归最经典的斐波那契数列JAVA程序拿出来。

       函数名:int getFibo(int n)

       输入:数组序号n,范围1,2,3...

       输出:getFibo(1)=getFibo(2)=1,getFibo(n+2)=getFibo(n+1)+getFibo(n)

public class MyCode1{
	public static void main(String[] args){
		for(int i=1;i<=10;i++){
			System.out.println(getFibo(i));
		}
	}

	public static int getFibo(int n){
		if(n==1) return 1;
		else if(n==2) return 1;
		else return (getFibo(n-1)+getFibo(n-2));
	}
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章