Java编程初级练习题11-20


前言

本文的目的旨在通过练习,提高逻辑思维能力,和算法优化能力。


11.排列问题 递归算法

题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 分析:多重for循环在数字少时可以用,数字一多书写很麻烦,显然不是合适算法。递归算法本质上时间复杂度跟for一样,但是书写简捷,可以理解为有顺序的取出三个数,每次取数不放回;分为3次向栈中放数字,如果栈中没有这个数字就放入,有就不放。
import java.util.Stack;

public class Main {
    static int count=0;//类变量
    static Stack<Integer> s = new Stack<Integer>();//类变量,可以直接在main里面用
    public static void fun(int minl,int maxl,int curnum,int maxnum) {
    	if(curnum==maxnum) {
    		count++;
    		System.out.println(s);
    		return;//结束函数调用
    	}
    	for(int i = minl; i <= maxl; i++){
            if(!s.contains(i)) {
	    		s.push(i);
	            fun(minl, maxl, curnum+1, maxnum);
	            s.pop();
            }
        }

    }
    public static void main (String[] args){
    	 fun(1, 4, 0, 3);
         System.out.println(count);
    }
}

12.奖金(等价于税收问题)

题目:企业发放的奖金根据利润提成。利润(I)低于或等于10万元时,奖金可提10%;利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可可提成7.5%;20万到40万之间时,高于20万元的部分,可提成5%;40万到60万之间时高于40万元的部分,可提成3%;60万到100万之间时,高于60万元的部分,可提成1.5%,高于100万元时,超过100万元的部分按1%提成,从键盘输入当月利润I,求应发放奖金总数?

分析,每次会用到之前分段的总和,可以利用函数内调用函数方式避免重复;

import java.util.Scanner;

public class Main {
	public static double premium(double profit){
        double premium = 0;
        if(profit>=0 && profit <= 100000){
            premium = profit*0.1;
        }else if(profit > 100000 && profit <= 200000){
            premium = (profit - 100000) * 0.075 + premium(100000);
        }else if(profit > 200000 && profit <= 400000){
            premium = (profit - 200000) * 0.05 + premium(200000);
        }else if(profit > 400000 && profit <= 600000){
            premium = (profit - 400000) * 0.03 + premium(400000);
        }else if(profit > 600000 && profit <= 1000000){
            premium = (profit - 600000) * 0.015 + premium(600000);
        }else{
            premium = (profit - 1000000) * 0.01 + premium(1000000);
        }
        return premium;
    }
	public static void main(String[] args) {
		// TODO Auto-generated method stub 
		Scanner in = new Scanner(System.in);
		System.out.println("请输入利润数:");
		double profit = in.nextDouble();
		System.out.println("奖金为"+premium(profit));
		in.close();
    }
}

13.完全平方数

题目:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少? 分析:先构造完全平方数判断函数;再循环找数。
import java.util.Scanner;

public class Main {
	public static boolean perfectsqure(int num){  
		boolean flag=false;
		if(num==0) {
			flag=true;
		}
		else {
			for(int i=1;i<Math.sqrt(num)+1;i++) {
				if((double)num/i==i)
					flag=true;
			}
		}
		return flag;
    }
	public static void main(String[] args) {
		// TODO Auto-generated method stub 
		Scanner in = new Scanner(System.in);
		int x=0;
		while(true) {
			if(perfectsqure(x+100) && perfectsqure(x+268)) {
				System.out.print("这个数是:"+x);
				break;
			}
			x++;
		}
		in.close();
    }
}

14、日期 函数内调用函数

题目:输入某年某月某日,判断这一天是这一年的第几天?
分析:题目有两个注意点一是闰年平年判断,二是字符串的拆解,此处计算天数用到了12题的技巧。

import java.util.Scanner;

public class Main {
	public static void day(String s){ 
		int day=0;
		String[] a = s.split("-");
		if(isleap(Integer.parseInt(a[0]))) {
			int mm=Integer.parseInt(a[1]);
			day=sumday(mm-1)+Integer.parseInt(a[2]);
		}
		else {
			int mm=Integer.parseInt(a[1]);
			if(mm>2)
				day=sumday(mm-1)+Integer.parseInt(a[2])-1;
			else
				day=sumday(mm-1)+Integer.parseInt(a[2]);
		}
		System.out.printf("第%s年的第%d天\n",a[0],day);
    }
	public static int sumday(int m) {
		int sum=0;
		switch (m){
	        case 1: sum=31; break;
	        case 2: sum=sumday(1)+29; break;
	        case 3: sum=sumday(2)+31; break;
	        case 4: sum=sumday(3)+30; break;
	        case 5: sum=sumday(4)+31; break;
	        case 6: sum=sumday(5)+30; break;
	        case 7: sum=sumday(6)+31; break;
	        case 8: sum=sumday(7)+31; break;
	        case 9: sum=sumday(8)+30; break;
	        case 10: sum=sumday(9)+31; break;
	        case 11: sum=sumday(10)+30; break;
	        default: break;
    }
		return sum;
	}
	public static boolean isleap(int y) {
		if(y%100!=0 && y%4==0 || y%400==0) {
			return true;
		}else
		{
			return false;
		}
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub 
		System.out.println("请输入日期,格式为yyyy-mm-dd:");
		Scanner in = new Scanner(System.in);
		String s = in.nextLine();
		day(s);	  
		in.close();
    }
}

15、比大小 冒泡排序

题目:输入三个整数x,y,z,请把这三个数由小到大输出
分析:简单可以直接用if,为了通用比较三个以上的,本处利用冒泡排序

public class Main {
	public static void sort(int...a ){ 
		for(int i=1;i<a.length;i++)
			for(int j=0;j<a.length-i;j++) {
				int temp=0;
				if(a[j]>a[j+1]) {
					temp=a[j];
					a[j]=a[j+1];
					a[j+1]=temp;
				}
			}
		for(int k: a) {
			System.out.print(k+" ");
		}
    }
	public static void main(String[] args) {
		// TODO Auto-generated method stub 
		sort(3,6,7,8,1,2,0);
    }
}

16、乘法口诀表

题目:输出9*9口诀。

public class Main {
	public static void main(String[] args) {
		for(int i=1;i<10;i++) {
			for(int j=1;j<=i;j++) {
				System.out.printf("%d*%d=%d ",j,i,i*j);
			}
		System.out.println();
		}
    }
}

17、猴子吃桃 递归算法

题目:猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少
分析:可以反过来看,第1天早上采了a个,第2天吃2(a+1),即f(n)=2(f(n-1)+1),已知第一天采了一个,第10天采了多少个,可采用递归算法

public class Main {
	public static int sum(int days){
        if(days == 1){
            return 1;
        }else if(days > 1){
            return (sum(days-1) + 1) * 2;
        }
        return 0;
    }
	public static void main(String[] args) {
		
        System.out.print(sum(10));
    }
}

18、抽签比赛

题目:两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。
分析;列出所有可能组合,将不符合的排除

public class Main{
	public static void main(String[] args) {
		for(char i ='x';i<='z';i++){
		    for(char j ='x';j<='z';j++){
		        if(i!=j)
		            for(char k = 'x';k<='z';k++){
		                if(i!=k&&j!=k)
		                    if(i!='x'&&k!='x'&&k!='z') {
		                    System.out.println("a与" + i + "比赛");
							System.out.println("b与" + j + "比赛");
							System.out.println("c与" + k + "比赛");
		                    }
		            }
		    }
		}
  }
}

19、打印菱形

题目:打印出如下图案(菱形)
分析:可以看做看做是由空格,*,组成,下一半开头缩进一个,每次少画一颗星,上一半刚好相反
在这里插入图片描述

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		System.out.println("请输入项数:");
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		//上一半
		for(int i=1;i<n;i++) {//倒过来画一遍
			for(int k=0;k<n-i;k++) {//表示缩进格数
				System.out.print(" ");
			}
			for(int j=n-i;j<n;j++) {//画的个数每次增加
					System.out.print("* ");
		     }
			System.out.println();//每层画完换行
		}
		//下一半
		for(int i=n;i>0;i--) {
			for(int k=0;k<n-i;k++) {//表示缩进格数
				System.out.print(" ");
			}
			for(int j=n-i;j<n;j++) {//画的个数每次减少
					System.out.print("* ");
		     }
			System.out.println();//每层画完换行
		}
        in.close();
    }
}

20、分数列求和 递归算法

题目:有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13…求出这个数列的前20项之和。
分析:分子分母都是斐波那契数列的一部分,斐波那契数列可以用递归算法给出

public class Main {
	public static int fib(int n) {
		if(n==1 || n==2)
			return 1;
		else
			return fib(n-1)+fib(n-2);
	}
	public static void main(String[] args) {
		System.out.println("请输入项数:");
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		double result=0;
		for(int i=0;i<n;i++) {
			result+=(double)fib(i+3)/fib(i+2);
		}
        System.out.printf("前%d项和为%.2f \n",n,result);
        in.close();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值