初级算法题
第一题:
古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,
小兔子长到第三个月后每个月又生一对兔子,
假如兔子都不死,问每个月的兔子总数为多少对?
public class Test01{
public int soluction(int month){
if (month<=2){
return 1;
}
//使用递归
return soluction(month-1)+soluction(month-2);
}
public static void main(String[] args){
for (int month=1;month<32;month++){
System.out.println(new Test01().soluction(month));
}
}
}
上一题分析:这是一个菲波那切数列问题
第二题:
题目:判断101-200之间有多少个素数,并输出所有素数。
public class Test02 {
public static void main(String[] args){
for (int i=101;i<=200;i++){
//使用Math.sqrt()是为了提高效率
for (int j=2;j<=Math.sqrt(i);j++){
if (i%j==0){
break;
}else if ((j+1)>Math.sqrt(i)){
System.out.println(i);
}
}
}
}
}
上一题分析:判断素数(质数)的方法:用这个数分别对2到sqrt(这个数)求余,如果余数为零,则表明此数不是素数,反之是素数。
第三题:
题目:题目:打印出所有的 "水仙花数 ",所谓 "水仙花数 "是指一个三位数,其各位数字立方和等于该数本身。
例如:153是一个 "水仙花数 ",因为153=1的三次方+5的三次方+3的三次方。
public class Test03 {
public static void main(String[] args){
for (int i=100;i<999;i++){
int a = i/100; //求百位数字
int b = i/10%10; //求十位数字
int c = i%10; //求个位数字
int newCount = a*a*a+b*b*b+c*c*c;
if (i==newCount){
System.out.println(i);
}
}
}
}
第四题:
题目:将一个正整数分解质因数。例如:输入90,打印出90=2x3x3x5。
质因数:在数论里是指能整除给定正整数的质数
import java.util.Scanner;
public class Test04 {
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int n = in.nextInt();
System.out.print(n+"=");
int k = 2; //最小质因子
while (k!=n) {
if (n > k&&n % k == 0) {
n = n / k;
System.out.print(k + "*");
} else {
k++;
}
}
System.out.print(k);
}
}
上一题分析:对n进行分解质因数,应先找到一个最小的质数k,然后按下述步骤完成:
(1)如果这个质数恰等于n,则说明分解质因数的过程已经结束,打印出即可。
(2)如果n>k,但n能被k整除,则应打印出k的值,并用n除以k的商作为新的正整数n,重复执行第一步。
(3)如果n不能被k整除,则用k+1作为k的值,重复执行第一步
第五题:
题目:输入两个正整数a和b,求其最大公约数(最大公因数)和最小公倍数
import java.util.Scanner;
public class Test05 {
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int a = in.nextInt();
int b = in.nextInt();
int c=0;
int d = a;
int e = b;
//确保a是两数中大的那个
if (a<b){
int temp = a;
a = b;
b = temp;
}
while (a>b){
c=a%b;
if (c==0){
break;
}
a=b;
b=c;
}
System.out.println(b);//最大公约数
System.out.println(d*e/b); //最小公倍数
}
}
上一题分析:
1.找出两数中较大的数,赋值给a,较小数赋值给b
2.求a对b的余数
3.余数为0则代表b就是最大公约数
4.余数不为0,则将b赋值给a,将上面的余数赋值给b,重复执行2
第六题:
题目:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
import java.util.Scanner;
public class Test06 {
public static void main(String[] args){
int ziMu = 0;
int kongGe = 0;
int shuZi = 0;
int qiTa = 0;
Scanner in = new Scanner(System.in);
String str = in.nextLine();
char [] arrry = str.toCharArray();
//用数组长度控制循环一般有两种写法
//i<arrry.length或者i<=arrry.length-1
//小建议:平时固定用一种即可,不要两种交换着用,免得出现写成i<arrry.length-1这种情况
for (int i=0;i<arrry.length;i++){
//值得注意的是if里不能'a'<=arrry[i]<='z'这样判断
//而要'a'<=arrry[i]&&arrry[i]<='z'这样判断
if ('a'<=arrry[i]&&arrry[i]<='z'||'A'<=arrry[i]&&arrry[i]<='Z'){
ziMu++;
}
if (' '==arrry[i]){
kongGe++;
}
if ('1'<=arrry[i]&&arrry[i]<='9'){
shuZi++;
}
}
qiTa = arrry.length-ziMu-kongGe-shuZi;
System.out.println("字母:"+ziMu+"个");
System.out.println("空格:"+kongGe+"个");
System.out.println("数字:"+shuZi+"个");
System.out.println("其他:"+qiTa+"个");
}
}
第七题:
题目:输入一个数a,输入一个数n
求a+aa+aaa+aaaa+aa…a的值,n代表相加数的个数
如:输入a=2,n=5
则输出:2+22+222+2222+22222的和
import java.util.Scanner;
public class Test07 {
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int a = in.nextInt();
int n = in.nextInt();
int sum=0;
int b=0; //为了不改变a的值,引入变量b
for (int i=0;i<n;i++){
b=b+a;
sum=sum+b;
b=b*10;
}
System.out.println(sum);
}
}
第八题:
题目:一个数如果恰好等于它的因子之和,这个数就称为 "完数 "。
例:6=1+2+3
要求:找出1000以内的所有完数。
提示:
因子:所有可以整除这个数的数,不包括这个数自身.
因数:所有可以整除这个数的数,包括这个数本身
public class Test08 {
public static void main(String[] args){
for (int i=2;i<1000;i++){
int a=0;
//这里用i/2是为了提高效率,因为一个数的因子最大不超过这个数的一半
for (int j=2;j<=i/2;j++){
if (i%j==0){
a=a+j;
}
}
a++;
if (a==i){
System.out.println(i);
}
}
}
}
第九题:
题目:一球从100米高度自由落下,每次落地后反弹回原高度的一半;再落下,
求它在第10次落地时,共经过多少米?第10次反弹多高?
public class Test09 {
public static void main(String[] args){
double a=100; //原始高度。注意:涉及小数运算应用double或者float类型
double count=100; //经过的路程
for (int i=1;i<10;i++){ //第一次弹起到第十次落地的过程
a=a/2;
count=count+2*a;
}
System.out.println("第10次落地时,共经过多少"+count+"米");
//落地后才反弹,所以第十次反弹在第十次落地之后,故反弹距离需再除以2
System.out.println("第10次反弹"+a/2+"米");
}
}
第十题:
题目:有1、2、3、4四个数字,能组成多少个互不相同,且同一个数中无重复数字的三位数?并把他们都输出
public class Test10 {
public static void main(String[] args){
int array[] = {1,2,3,4};
int count=0;
for (int i=0;i<4;i++){
for (int j=0;j<4;j++) {
if (array[i] != array[j]) {
for (int k = 0; k < 4; k++) {
if (array[k]!=array[i]&&array[k]!=array[j]){
count++;
System.out.println(array[i]*100+array[j]*10+array[k]);
}
}
}
}
}
System.out.println("这样的数共有"+count+"个");
}
}
上一题分析:
乍看之下有点无从下手,其实找个"1",画一下"1"的三层树状图就明白了
第十一题:
题目:企业发放的奖金根据利润提成。利润低于或等于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%提成;
从键盘输入当月利润,求应发放奖金总数?
import java.util.Scanner;
public class Test11 {
public static void main(String[] args){
Scanner input=new Scanner(System.in);
double x=input.nextDouble();
double y=0;
if(x>0&&x<=10){
y=x*0.1;
}else if(x>10&&x<=20){
y=10*0.1+(x-10)*0.075;
}else if(x>20&&x<=40){
y=10*0.1+10*0.075+(x-20)*0.05;
}else if(x>40&&x<=60){
y=10*0.1+10*0.075+20*0.05+(x-40)*0.03;
}else if(x>60&&x<=100){
y=10*0.1+10*0.075+20*0.05+20*0.03+(x-60)*0.015;
}else if (x>100){
y=10*0.1+10*0.075+20*0.05+20*0.03+40*0.015+(x-100)*0.01;
}
System.out.println(y);
}
}
第十二题:
题目:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?
public class Test12 {
public static void main(String[] args){
for (int i=-100;i<10000;i++){
int a=i+100;
//之所以用j<=a/2+1,是因为没有一个正数的平方根会大于它的一半加1
for (int j=1;j<=a/2+1;j++){
//注意:这里不能用a%j==0&&j==a%j进行判断,不然得不到结果
if (a%j==0&&j==a/j){
a=a+168;
for (int k=1;k<=a/2+1;k++){
if (a%k==0&&k==a/k){
System.out.println(i);
}
}
}
}
}
}
}
第十三题:
题目:输入某年某月某日,判断这一天是这一年的第几天?
输入:2019.03.12
输出:2019.3.12是这一年的第71天
import java.util.Scanner;
public class Test13 {
public static void main(String[] args){
Scanner in = new Scanner(System.in);
String str = in.nextLine();
int year = 0;
int month = 0;
int day = 0;
int erYue = 0;
year = new Integer(str.substring(0,str.indexOf(".")));
month = new Integer(str.substring(str.indexOf(".")+1,str.lastIndexOf(".")));
day = new Integer(str.substring(str.lastIndexOf(".")+1,str.length()));
if (year%4==0&&year%100!=0){
erYue = 29;
}
else if (year%400==0){
erYue=29;
}else {
erYue=28;
}
switch (month){
case 1:
day=day;
break;
case 2:
day=day+31;
break;
case 3:
day=day+31+erYue;
break;
case 4:
day=day+31+erYue+31;
break;
case 5:
day=day+31+erYue+31+30;
break;
case 6:
day=day+31+erYue+31+30+31;
break;
case 7:
day=day+31+erYue+31+30+31+30;
break;
case 8:
day=day+31+erYue+31+30+31+30+31;
break;
case 9:
day=day+31+erYue+31+30+31+30+31+31;
break;
case 10:
day=day+31+erYue+31+30+31+30+31+31+30;
break;
case 11:
day=day+31+erYue+31+30+31+30+31+31+30+31;
break;
case 12:
day=day+31+erYue+31+30+31+30+31+31+30+31+30;
break;
}
System.out.println(str+"是这一年的第"+day+"天");
}
}
上一题分析:
先判断是否为闰年,再确定每月有多少日
闰年口诀:四年一闰;百年不闰,四百年再闰;
第十四题:
题目:输出9*9口诀
public class Test14 {
public static void main(String[] args){
for (int i=1;i<10;i++){
for (int j=1;j<=i;j++){
System.out.print(j+"x");
System.out.print(i+"=");
System.out.print(i*j+" ");
}
System.out.println();
}
}
}
第十五题:
题目:两个乒乓球队进行比赛,各出三人。
甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。
有人向队员打听比赛的名单。
a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。
public class Test15 {
public static void main(String[] args){
char i=0;
char j=0;
char k=0;
for (i='x';i<='z';i++){
if (i!='x'&&i!='z'){
System.out.println("c"+i);
break;
}
}
for (j='x';j<='z';j++){
if (j!='x'&&j!=i){
System.out.println("a"+j);
break;
}
}
for (k='x';k<='z';k++){
if (k!=i&&k!=j){
System.out.println("b"+k);
break;
}
}
}
}
第十六题:
题目:打印一个菱形
public class Test16 {
public static void main(String[] args){
int y=9; //上半部分层数
int k=1;
int m=1;
for (int i=y;i>0;i--){ //控制打印的上半部分层数
for (int j=1;j<i;j++){ //控制每层空格数
System.out.print(" ");
}
for (int j=1;j<=k;j++){
if (j==k){
System.out.println("*");
}else {
System.out.print("*");
}
}
k=k+2;
}
for (int i=y-1;i>0;i--){ //控制打印的下半部分层数
for (int j=0;j<m;j++){ //控制每层空格数
System.out.print(" ");
}
k=k-2;
for (int j=1;j<=k-2;j++){
if (j==k-2){
System.out.println("*");
}else {
System.out.print("*");
}
}
m=m+1;
}
}
}
第十七题:
题目:有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13…求出这个序列的前20项之和。
public class Test17 {
public static void main(String[] args){
double sum=0;
Test17 test = new Test17();
for (int i=1;i<=20;i++){
sum = sum+test.fenZi(i)/test.fenMu(i);
}
System.out.print(sum);
}
public double fenMu(int a){
if (a==1){
return 1;
}
if (a==2){
return 2;
}
return fenMu(a-1)+fenMu(a-2);
}
public double fenZi(int b){
if (b==1){
return 2;
}
if (b==2){
return 3;
}
return fenZi(b-1)+fenZi(b-2);
}
}
上一题分析:
分子分母都是有规律的数列,直接递归求每一项的分子分母
第十八题:
利用递归方法求5!
public class Test18 {
public static void main(String[] args){
System.out.print(new Test18().diGui(5));
}
public int diGui(int a){
if (a==1){
return 1;
}
return a*diGui(a-1);
}
}
第十九题:
题目:给一个不多于5位的正整数
输出要求:一、它是几位数,二、逆序打印出各位数字。
import java.util.Scanner;
public class Test19 {
public static void main(String[] args){
Scanner in = new Scanner(System.in);
char[] array = in.nextLine().toCharArray();
System.out.println("这是一个"+array.length+"位数");
for (int i=array.length-1;i>=0;i--){
System.out.print(array[i]);
}
}
}
上一题分析:
可以巧妙利用字符数组解决该题
第二十题:
题目:判断一个数是不是回文数。
例如:输入123321,输出“是回文数”
输入12,输出“不是回文数”
import java.util.Scanner;
public class Test20 {
public static void main(String[] args){
int i;
Scanner in = new Scanner(System.in);
char[] array = in.nextLine().toCharArray();
for (i=0;i<=array.length/2;i++){
if (array[i]!=array[array.length-1-i]){
break;
}
}
if (i==array.length/2+1){
System.out.println("是回文数");
}else{
System.out.println("不是回文数");
}
}
}
如果这篇博文对您有帮助的话,别忘了右上角点赞哈