【思特奇杯.云上蓝桥-算法训练营】第1周

1. 跑步训练

问题描述
小明要做一个跑步训练,初始时,小明充满体力,体力值计为 10000。

如果小明跑步,每分钟损耗 600 的体力。
如果小明休息,每分钟增加 300 的体力。
体力的损耗和增加都是 均匀变化的。

小明打算跑一分钟、休息一分钟、再跑一分钟、再休息一分钟……如此循环。
如果某个时刻小明的体力到达 0,他就停止锻炼, 请问小明在多久后停止锻炼。
为了使答案为整数,请以秒为单位输出答案,答案中只填写数,不填写单位。

思路分析:设置一个标志isRun 表示是否此次跑步,如果跑步体力-600,如果是休息那么体力+300. 把这两个判断放在while(true) 循环当中,如果发现某次体力值不足600,但这次isRun= true,那么就跳出循环,计算总的时间。

package com.test;

public class RunningTest {
	public static void main(String[] args) {
		int energy=10000;
		boolean isRun=true;
		
		int sec=0;
		int min=0;
		
		while(true) {
			if(energy<600&&isRun) break;
			if(isRun) {
				energy-=600;
				isRun=false;
				min++;
			}else {
				energy+=300;
				isRun=true;
				min++;
			}
		}
		
		sec=min*60+energy/10;
		
		System.out.println(sec);
		 	
	}
}

2.阶乘约数

问题描述
定义阶乘 n! = 1 × 2 × 3 × ··· × n。
请问 100! (100 的阶乘)有多少个约数。

思路分析:数学公式->任意一个正整数 X 都可以表示成若干个质数乘积的形式,即 X = p1α1 ∗ p2α2 …… ∗ pkαk

约数个数 = (a1 + 1)(a2 + 1)……(ak + 1)

package com.test;

import java.util.ArrayList;
import java.util.List;

public class Factorial {
	private static List<Integer> asList;

	public static void main(String[] args) {
		List<Integer> primeList=new ArrayList<Integer>();
		boolean flag=true;
		for(int i=2;i<=100;i++) {
			flag=true;
			for(int j=2;j<=i-1;j++) {
				if(i%j==0) {
					flag=false;
					break;
				}
			}
			if(flag) {
				primeList.add(i);
			}
		}
		for(int i:primeList) {
			System.out.print(i+",");
		}
		System.out.println();
		Long result=1L;
		int [] arr=new int[] {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};
		int size = arr.length;
		for(int i=0;i<size;i++) {
			int mc=0;int n=100;
			while(n!=0) {
				mc+=(n/=arr[i]);		
			}
			result*=(mc+1);
		}
		
		System.out.println(result);
		
	}
}

2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,
答案:39001250856960000

3.出栈次序

X 星球特别讲究秩序,所有道路都是单行线。一个甲壳虫车队,共 16 辆车,按照编号先后发车,夹在其它车流中,缓缓前行。路边有个死胡同,只能容一辆车通过,是临时的检查站,如图所示
X 星球太死板,要求每辆路过的车必须进入检查站,也可能不检查就放行,也可能仔细检查。如果车辆进入检查站和离开的次序可以任意交错。那么,该车队再次上路后,可能的次序有多少种?为了方便起见,假设检查站可容纳任意数量的汽车。显然,如果车队只有 1 辆车,可能次序 1 种;2 辆车可能次序 2 种;3 辆车可能次序 5 种。

现在足足有 16 辆车啊,亲!需要你计算出可能次序的数目
在这里插入图片描述

思路分析:
定义递归函数recur(int m,int n);

m表示左边的车辆数,n表示检查站的车辆数。
递归思想—> 递归终点是,m=0时,无论n为多少结果都为1然后,递归关系分两种情况:当n=0时,即检查站的车辆数为0,recur(m,n)=recur(m-1,1);当检查站有车后,即n!=0,那么recur(m,n)= recur(m-1, n+1)+recur(m, n-1)

package com.test;

public class Planet {
	public static void main(String[] args) {
		Long resultLong=recur(16, 0);
		System.out.println(resultLong);
		
	}
	//m表示左边的车数,n表示再检查站中的车数.
	public static Long recur(int m,int n) {
		if(m==0) return 1L;
		if(n==0) return recur(m-1, 1);
		if(n>0) return  recur(m-1, n+1)+recur(m, n-1);
		
		return 0L;
	}
}

答案:35357670

4.哥德巴赫分解

在这里插入图片描述
思路分析:
先遍历10000 ---- 4 的所有偶数,再从 所有从3开始的素数中找最小的那个素数,然后再找出最大的.

package com.test;

public class Decompose {
	public static void main(String[] args) {
		int n=10000;
		int m=0;
		for(int i=n;i>3;i-=2) {
			for(int j=1;j<(i+1)/2;j+=2) {
				if(isPrime(j)&&isPrime(i-j)) {
					m=Math.max(m, j);
					break;
				}
			}
		}
		System.out.println(m);
	}
	
	public static boolean isPrime(int num) {
		 if (num == 1) return false;
		    for (int i = 2; i*i < num+1; i++)
		        if (num % i == 0) return false;
		    return true;
			
	}
		

}
答案: 173

5. 图书排列

题目
将编号为1~10的10本书排放在书架上,要求编号相邻的书不能放在相邻的位置。

请计算一共有多少种不同的排列方案。
注意,需要提交的是一个整数,不要填写任何多余的内容。

解题思路:
利用深度优先搜索遍历,将不符合条件的的筛选掉

package com.test;

import java.util.LinkedList;

public class DFS01 {
	public static void main(String[] args) {
		int[] options = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
		LinkedList<Integer> list = new LinkedList<Integer>();
		test t1 = new test();
		t1.dfs(list, options);
		System.out.println(t1.count);
	}

}

class test {
	int count;

	public void dfs(LinkedList<Integer> path, int[] options) {
		int n = options.length;

		if (path.size() == n) {
			count++;
			return;
		}

		for (int i = 0; i < n; i++) {
			if (path.contains(options[i]))
				continue;
			int[] wrongOpts = null;
			if (path.size() != 0) {
				wrongOpts = wrongOpt(path.getLast());
				boolean flag = true;
				for (int j = 0; j < wrongOpts.length; j++) {
					flag = true;
					if (options[i]==wrongOpts[j]) {
						flag = false;
						break;
					}
				}
				if (flag) {
					path.add(options[i]);
					dfs(path, options);
					path.removeLast();
				}
			} else {
				path.add(options[i]);
				dfs(path, options);
				path.removeLast();
			}
		}

	}

	public int[] wrongOpt(int i) {
		if (i == 1) {
			return new int[] { 2 };
		} else if (i == 2) {
			return new int[] { 1, 3 };
		} else if (i == 3) {
			return new int[] { 2, 4 };
		} else if (i == 4) {
			return new int[] { 3, 5 };
		} else if (i == 5) {
			return new int[] { 4, 6 };
		} else if (i == 6) {
			return new int[] { 5, 7 };
		} else if (i == 7) {
			return new int[] { 6, 8 };
		} else if (i == 8) {
			return new int[] { 7, 9 };
		} else if (i == 9) {
			return new int[] { 8, 10 };
		} else if (i == 10) {
			return new int[] { 9 };
		} else {
			return null;
		}

	}
}
答案:479306

6. 猴子分香蕉

在这里插入图片描述

package com.test;

public class Banana {
	public static void main(String[] args) {
		int n=6;
		
		while(true) {
			if(n%5==1) {
				//第二个猴子醒来时的香蕉数量
				int a=(n-1)/5*4;
				if(a%5==2) {
					//第三只猴子醒来时的香蕉数量
					int b=(a-2)/5*4;
					if(b%5==3) {
						//第四只猴子醒来时的香蕉的数量
						int c=(b-3)/5*4;
						if(c%5==4) {
							int d=(c-4)/5*4;
							//第五只猴子醒来时香蕉的数量
							if(d%5==0&&d!=0) {
								System.out.println(n);
								break;
							}
						}
					}
				}
			}
			n++;
				
		}
	}
	
	
}
答案:3141

7.稍小分数

回到小学----
真分数:分子小于分母的分数
既约分数:分子分母互质,也就是说最大公约数是1

x星球数学城的入口验证方式是:
屏幕上显示一个真分数,需要你快速地找到一个比它小的既约分数,要求这个分数越大越好。
同时限定你的这个分数的分母不能超过100。

如下代码很暴力地解决了这个问题,请仔细分析,并填写划线部分缺失的代码。

package com.test;

public class FenShu {
	public static void main(String[] args) {
		int a = 7;
		int b = 13;

		int m, n;
		int max_a = 0;
		int max_b = 1;

		for (n = 100; n > 1; n--) {
			for (m = n - 1; m >= 1; m--) {
				if (m * b < a * n && isPrimeEachOther(m, n)) {
					if (max_a * n < max_b * m) { // 填空
						max_a = m;
						max_b = n;
						break;
					}
				}
			}
		}
		System.out.printf("%d/%d",max_a,max_b);

	}

	public static boolean isPrimeEachOther(int m, int n) {
		boolean f1=true; boolean f2=true;
		for(int i=2;i<m;i++) {
			if(m%2==0) {
				f1=false;
				break;
			}
		}
		for(int i=2;i<n;i++) {
			if(n%2==0) {
				f2=false;
				break;
			}
		}
		return f1&&f2;
		
	}
}

答案: 51/95

8.excel地址

问题描述

Excel单元格的地址表示很有趣,它使用字母来表示列号。
  比如,
  A表示第1列,
  B表示第2列,
  Z表示第26列,
  AA表示第27列,
  AB表示第28列,
  BA表示第53列,
  …
  当然Excel的最大列号是有限度的,所以转换起来不难。
  如果我们想把这种表示法一般化,可以把很大的数字转换为很长的字母序列呢?
  本题目即是要求对输入的数字, 输出其对应的Excel地址表示方式。

样例输入
26
样例输出
Z

样例输入
2054
样例输出
BZZ

import java.util.Scanner;
import java.util.Stack;
public class Excel地址 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        Stack<Integer> stack = new Stack();
        /*核心部分 Start*/
        while(n!=0){
            if(n%26==0) n-=26;
            stack.push(n%26==0?26:n%26);
            n/=26;
        }
        /*核心部分 End*/
       while (!stack.isEmpty())
            System.out.print((char)('A'+stack.pop().intValue()-1));
       sc.close();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值