19201310程习恩
1题 跑步训练
问题描述
小明要做一个跑步训练,初始时,小明充满体力,体力值计为 10000。
如果小明跑步,每分钟损耗 600 的体力。
如果小明休息,每分钟增加 300 的体力。
体力的损耗和增加都是 均匀变化的。
小明打算跑一分钟、休息一分钟、再跑一分钟、再休息一分钟……如此循环。
如果某个时刻小明的体力到达 0,他就停止锻炼,
请问小明在多久后停止锻炼。
为了使答案为整数,请以秒为单位输出答案,答案中只填写数,不填写单位。
答案提交
3880
public class Test1 { public static void main(String[] args) { int strength = 10000; int second = 0; System.out.println(train(10000)); } public static int train(int strength){ int second = 0; while (strength > 0){ for(int i = 0;i < 60;i++){ strength-=10; second++; if(strength <= 0){ return second; } } for(int i = 0;i < 60;i++){ strength+=5; second++; } } return second; } }
2题 阶乘约数
问题描述
定义阶乘 n! = 1 × 2 × 3 × ··· × n 。
请问 100! ( 100 的阶乘)有多少个约数。
答案提交
39001250856960000
public class Test2 { public static void main(String[] args){ int[] flag = new int[105]; for (int i = 2; i <= 100; i++) { int tmp = i; for (int j = 2; j <= tmp/j; j++) { while (tmp % j == 0) { flag[j]++; tmp /= j; } } if(tmp>1)flag[tmp]++; } long ans = 1; for (int i = 1; i <= 100; i++) { ans = ans*(flag[i] + 1); } System.out.println(ans); } }
3题 出栈次序
问题描述
X 星球特别讲究秩序,所有道路都是单行线。
一个甲壳虫车队,共 16 辆车,按照编号先后发车,夹在其它车流中,缓缓前行。
路边有个死胡同,只能容一辆车通过,是临时的检查站,如图所示。
X 星球太死板,要求每辆路过的车必须进入检查站,也可能不检查就放行,也可
能仔细检查。
如果车辆进入检查站和离开的次序可以任意交错。
那么,该车队再次上路后,可能的次序有多少种?
为了方便起见,假设检查站可容纳任意数量的汽车。
显然,如果车队只有 1 辆车,可能次序 1 种;2 辆车可能次序 2 种;3 辆车可能
次序 5 种。
现在足足有 16 辆车啊,亲!需要你计算出可能次序的数目。
答案提交
35357670
public class Test3 { public static void main(String[] args) { System.out.println(find(16, 0)); } public static int find(int wait,int enter){ if(wait == 0){ return 1; } if(enter == 0){ return find(wait - 1,1); } return find(wait - 1,enter + 1) + find(wait,enter - 1); } }
4题 哥德巴赫分解
题目如下:
哥德巴赫猜想认为:不小于4的偶数都可以表示为两个素数的和。
你不需要去证明这个定理,但可以通过计算机对有限数量的偶数进行分解,验证是否可行。
实际上,一般一个偶数会有多种不同的分解方案,我们关心包含较小素数的那个方案。
对于给定数值范围,我们想知道这些包含较小素数方案中最大的素数是多少。
比如,100以内,这个数是19,它由98的分解贡献。
你需要求的是10000以内,这个数是多少?
答案提交
173
public class Q4 { public static void main(String[] args) { final int max = 10005; int res = 0; boolean[] isPrime = new boolean[max]; int[] prime = new int[max]; for (int i = 0; i < max; i++) { isPrime[i] = true; } for(int i = 2; i < 10000; i++){ if(isPrime[i]){ prime[++prime[0]] = i; for(int j = i + i; j < 10000; j += i){ isPrime[j] = false; } } } for(int i = 4; i < 10000; i += 2) { for(int j = 1;j <= prime[0]; j++) { int t= i- prime[j]; if(t > 0 && isPrime[t]) { res = Math.max(res, prime[j]); break; } } } System.out.println(res); } }
5题 图书排列
题目描述
将编号为 1~10 的 10 本书排放在书架上,要求编号相邻的书不能放在相邻的位
置。
请计算一共有多少种不同的排列方案。
注意,需要提交的是一个整数,不要填写任何多余的内容。
答案提交
479306
public class Test5 { static int res = 0; public static boolean check(int[] a) { int l = a.length; for(int i = 0; i < l - 1; i++) { if(Math.abs(a[i] - a[i + 1]) == 1) { return false; } } return true; } public static void swap(int[] a, int x, int y) { int temp = a[x]; a[x] = a[y]; a[y] = temp; } public static void sort(int[] a, int begin, int end) { if(begin == end) { if(check(a)) res++; } for(int i = begin; i <= end; i++) { swap(a,begin,i); sort(a,begin+1,end); swap(a,begin,i); } } public static void main(String[] args) { int[] a ={1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; sort(a, 0, a.length-1); System.out.println(res); } }
5只猴子是好朋友,在海边的椰子树上睡着了。这期间,有商船把一大堆香蕉忘记在沙滩上离去。
第1只猴子醒来,把香蕉均分成5堆,还剩下1个,就吃掉并把自己的一份藏起来继续睡觉。
第2只猴子醒来,重新把香蕉均分成5堆,还剩下2个,就吃掉并把自己的一份藏起来继续睡觉。
第3只猴子醒来,重新把香蕉均分成5堆,还剩下3个,就吃掉并把自己的一份藏起来继续睡觉。
第4只猴子醒来,重新把香蕉均分成5堆,还剩下4个,就吃掉并把自己的一份藏起来继续睡觉。
第5只猴子醒来,重新把香蕉均分成5堆,哈哈,正好不剩!
请计算一开始最少有多少个香蕉。
需要提交的是一个整数,不要填写任何多余的内容。
答案提交
3141
public class Test6 { public static void main(String[] args) { for(int banana = 6; ; banana += 5){ int temp = banana; // 第一只猴子 if(temp%5 == 1){ temp = (temp - 1) / 5 * 4; }else{ continue; } // 第二只猴子 if(temp % 5 == 2){ temp = (temp - 2) / 5 * 4; }else{ continue; } // 第三只猴子 if(temp % 5 == 3){ temp = (temp - 3) / 5 * 4; }else{ continue; } // 第四只猴子 if(temp % 5 == 4){ temp = (temp - 4) / 5 * 4; }else{ continue; } // 第二只猴子 if(temp > 0 && temp % 5 == 0){ System.out.println(banana); break; } } } }
7题 稍小分数
回到小学 ----
真分数:分子小于分母的分数
既约分数:分子分母互质,也就是说最大公约数是 1
x 星球数学城的入口验证方式是:
屏幕上显示一个真分数,需要你快速地找到一个比它小的既约分数,要求这个
分数越大越好。
同时限定你的这个分数的分母不能超过 100 。
public class Test7 { 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 && gcd(m, n) == 1){ if(m * max_b > n * max_a){ max_a = m; max_b = n; break; } } } } System.out.println(max_a + "/" + max_b); } public static int gcd(int a, int b){ if(b == 0) return a; return gcd(b, a % b); } }
8题 excel 地址
问题描述
Excel 单元格的地址表示很有趣,它使用字母来表示列号。
比如,
A 表示第 1 列,
B 表示第 2 列,
Z 表示第 26 列,
AA 表示第 27 列,
AB 表示第 28 列,
BA 表示第 53 列,
....
当然 Excel 的最大列号是有限度的,所以转换起来不难。
如果我们想把这种表示法一般化,可以把很大的数字转换为很长的字母序列
呢?
本题目即是要求对输入的数字, 输出其对应的 Excel 地址表示方式。
样例输入
26 样例输出
Z
样例输入
2054
样例输出
BZZ
public class Test8 { public static void main(String[] args) { long x, temp; int post = 0,i; Scanner sc = new Scanner(System.in); x = sc.nextInt(); //判断整除小于最高位数 for(i = 0; i < 20; i++){ if((x / Math.pow(26, i)) < 1){ post = i; break; } } int[] a= new int[post]; for (int j = 0; j < post; j++) { a[j] = 0; } temp = x; //26进制化,只有1-26,没有0,存储方式是低位在左,高位在右 for(i = 0; i < post; i++){ a[i] = (int) (temp % 26); temp = temp / 26; } int j; //借用冒泡排序的方法实现借位思想 //循环保证每次从低位到高位扫描不出现小于等于0的数 for(i = 0; i < post; i++){ for(j = i; j < post; j++){ if(a[j] <= 0){ if(j == post - 1 && a[j] == 0){ continue;//最高位原来如果为1,借位变成0,最高位不用变 } a[j + 1] = a[j+1] - 1; a[j]= 26 + a[j]; } } } int flag = 0; //从后往前输出 for(i = post - 1; i >= 0; i--){ if(a[i] != 0 || flag == 1){ flag = 1; System.out.print((char)('A'+a[i]-1)); } } } }
9题 日期问题
小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日
期都在 1960 年 1 月 1 日至 2059 年 12 月 31 日。令小明头疼的是,这些日期采
用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年
的。更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多
可能的日期与其对应。
比如 02/03/04,可能是 2002 年 03 月 04 日、2004 年 02 月 03 日或 2004 年 03
月 02 日。 给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?
输入
一个日期,格式是"AA/BB/CC"。 (0 <= A, B, C <= 9)
输出
输出若干个不相同的日期,每个日期一行,格式是"yyyy-MM-dd"。多个日期按
从早到晚排列。
样例输入
02/03/04
样例输出
2002-03-04
2004-02-03
2004-03-02
public class Q9 { static ArrayList<Data> data = new ArrayList<>(); public static void main(String[] args) { Scanner sc = new Scanner(System.in); //把题目中给的数据进行分割处理 String[] tmp = sc.nextLine().trim().split("/"); //添加日期的所有可能组合情况 data.add(new Data(Integer.parseInt(tmp[0]),Integer.parseInt(tmp[1]),Integer.parseInt(tmp[2]))); data.add(new Data(Integer.parseInt(tmp[2]),Integer.parseInt(tmp[1]),Integer.parseInt(tmp[0]))); data.add(new Data(Integer.parseInt(tmp[2]),Integer.parseInt(tmp[0]),Integer.parseInt(tmp[1]))); //对日期去重 wipeRepeat(); //判断日期合法性 check(); //对合法的日期进行排序 sort(); //输出合法的日期 for(Data d : data) { System.out.println(d.toString()); } } //对合法日期进行排序 static void sort() { for(int i = 0; i < data.size()-1; i++) { for(int j = i+1; j < data.size(); j++) { int year1 = data.get(i).year; int year2 = data.get(j).year; int month1 = data.get(i).month; int month2 = data.get(j).month; int day1 = data.get(i).day; int day2 = data.get(j).day; if(year1 > year2) { change(i,j); }else if(year1 == year2) { if(month1 > month2) { change(i,j); }else if(month1 == month2) { if(day1 > day2) { change(i,j); } } } } } } //对两个合法的日期进行交换 static void change(int i, int j) { Data temp = data.get(i); data.set(i, data.get(j)); data.set(j, temp); } //判断日期的合法性 static void check() { for(int i = 0; i < data.size(); i++) { int year = data.get(i).year; int month = data.get(i).month; int day = data.get(i).day; //月份在1-12之间 if(month < 1 || month > 12) { data.remove(i); //迭代判断 check(); return ; } //大月有31天 if(month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) { if(day < 1 || day > 31) { data.remove(i); //迭代判断合法性 check(); return ; } } //小月有30天 if(month == 4 || month == 6 || month == 9 || month == 11) { if(day < 1 || day > 30) { data.remove(i); check(); return ; } } //闰年的2月为29天 if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0) { if(month == 2) { if(day < 1 || day > 29) { data.remove(i); //迭代进行判断 check(); return ; } } } //平年的2月有28天 else { if(month == 2) { if(day < 1 || day > 28) { data.remove(i); check(); return ; } } } } } //去重方法 static void wipeRepeat() { for(int i = 0; i < data.size(); i++) { for(int j = i+1; j < data.size(); j++) { if(data.get(i).year == data.get(j).year && data.get(i).month == data.get(j).month && data.get(i).day == data.get(j).day) { data.remove(i); //迭代去重 wipeRepeat(); return ; } } } } } class Data { int year; int month; int day; public Data(int year,int month,int day) { //这里确保年份在1960-2059之间 if(year >= 60) { this.year = year + 1900; }else { this.year = year + 2000; } this.month = month; this.day = day; } //重写toString方法,日期格式化处理一下 @Override public String toString() { if(month < 10 && day < 10) return year + "-0" + month + "-0" + day; else if(month < 10 && day >= 10) return year + "-0" + month + "-" + day; else if(month >= 10 && day < 10) return year + "-" + month + "-0" + day; else return year + "-" + month + "-" + day; } }
对于一个正整数n的划分,就是把n变成一系列正整数之和的表达式。注意,分划与顺序无关,例如6=5+1.跟6=1+5是同一种分划,另外,这个整数本身也是一种分划。
例如:,对于正整数n=5,可以划分为:
1+1+1+1+1
1+1+1+2
1+1+3
1+2+2
2+3
1+4
5
输入描述
输入一个正整数n
输出描述
输出n整数划分的总数k
输入样例
5
输出样例
7
public class Test10 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); if(n >= 1) { System.out.println(Div(n,n)); } } public static int Div(int n, int m){ if(n == 1||m == 1) return 1; else if(n < m) return Div(n,n); else if(n == m) return 1+Div(n,n-1); else return Div(n,m-1) + Div(n-m,m); } }
11题一步之遥
从昏迷中醒来,⼩明发现⾃⼰被关在 X 星球的废矿⻋⾥。
矿⻋停在平直的废弃的轨道上。
他的⾯前是两个按钮,分别写着“ F ”和“ B ”。
⼩明突然记起来,这两个按钮可以控制矿⻋在轨道上前进和后退。
按 F ,会前进 97 ⽶。按 B 会后退 127 ⽶。
透过昏暗的灯光,⼩明看到⾃⼰前⽅ 1 ⽶远正好有个监控探头。
他必须设法使得矿⻋正好停在摄像头的下⽅,才有机会争取同伴的援助。
或许,通过多次操作 F 和 B 可以办到。
矿⻋上的动⼒已经不太⾜,⻩⾊的警示灯在默默闪烁 ...
每次进⾏ F 或 B 操作都会消耗⼀定的能量。
⼩明⻜快地计算,⾄少要多少次操作,才能把矿⻋准确地停在前⽅ 1 ⽶远的地
⽅。
请填写为了达成⽬标,最少需要操作的次数。
注意,需要提交的是⼀个整数,不要填写任何⽆关内容(⽐如:解释说明等
答案提交
97
public class Test11 { static final int N = 1000; public static void main(String[] args) { int min=2*N+1; for(int B=0;B<=N;B++){ for(int F=0;F<=N;F++){ if(97*F-127*B==1){ if(F+B<min){ min=F+B; System.out.println("F: " + F); System.out.println("B: " + B); } } } } System.out.println(min);; } }
12题 X星球的机器⼈表演拉拉队有两种服装,A和B。
他们这次表演的是搭机器⼈塔。
类似:
A
B B
A B A
A A B B
B B B A B
A B A B B A
队内的组塔规则是:
A 只能站在 AA 或 BB 的肩上。
B 只能站在 AB 或 BA 的肩上。
你的任务是帮助拉拉队计算⼀下,在给定A与B的⼈数时,可以组成多少种花样
的塔。
输⼊⼀⾏两个整数 M 和 N,空格分开(0<M,N<500),分别表示A、B的⼈
数,保证⼈数合理性。
要求输出⼀个整数,表示可以产⽣的花样种数。
例如:
⽤户输⼊:
1 2
程序应该输出:
3
再例如: ⽤户输⼊:
3 3
程序应该输出:
4
public class Q12 { static final int N = 505; static int ans, m, n; static char[][] a = new char[N][N]; public static void main(String[] args) { Scanner sc = new Scanner(System.in); n = sc.nextInt(); m = sc.nextInt(); dfs(1,1,n,m); System.out.println(ans); } public static void dfs(int i, int j, int an, int am){ if(an == 0 && am == 0) { ans++; return; } int x,y; if(i==j) { x = i + 1; y = 1; } else { x = i; y = j + 1; } if(j==1){ if(an-1>=0){ a[i][j]='A'; dfs(x,y,an-1,am); } if(am-1>=0){ a[i][j]='B'; dfs(x,y,an,am-1); } } else { if(a[i-1][j-1]=='A'){ if(a[i][j-1]=='B'){ if(am-1>=0){ a[i][j]='B'; dfs(x,y,an,am-1); } } else { if(an-1>=0){ a[i][j]='A'; dfs(x,y,an-1,am); } } } else { if(a[i][j-1]=='B'){ if(an-1>=0){ a[i][j]='A'; dfs(x,y,an-1,am); } } else { if(am-1>=0){ a[i][j]='B'; dfs(x,y,an,am-1); } } } } } }
13题 七星填空
如下图所示。在七角星的 14 个节点上填入 1 ~ 14 的数字,不重复,不遗漏。
要求每条直线上的四个数字之和必须相等。
图片描述
图中已经给出了 3 个数字。 请计算其它位置要填充的数字,答案唯一。
填好后,请输出绿色节点的 4 个数字(从左到右,用空格分开)。
答案提交
10 3 9 8
public class Test13 { static int[] a = {1, 2, 3, 4, 5, 7, 8, 9, 10, 12, 13}; static int [] b; static boolean[] c, d; public static void main(String[] args) { c = new boolean[14]; d = new boolean[14]; b = new int[14]; b[0] = 6; b[8] = 14; b[10] = 11; c[0] = true; c[8] = true; c[10] = true; f(0); } private static void f(int i) { // 剪枝 if (i == 9) { if (b[1] + b[2] + b[3] + b[4] != b[0] + b[2] + b[5] + b[8]) { return; } } if (i == 11) { if (b[1] + b[2] + b[3] + b[4] != b[0] + b[3] + b[6] + b[10]) { return; } } if (i == 12) { if (b[1] + b[2] + b[3] + b[4] != b[1] + b[5] + b[7] + b[11]) { return; } } if (i == 13) { if (b[1] + b[2] + b[3] + b[4] != b[9] + b[10] + b[11] + b[12]) { return; } } if (i == 14) { if (b[1] + b[2] + b[3] + b[4] != b[7] + b[8] + b[12] + b[13]) { return; } if (b[1] + b[2] + b[3] + b[4] != b[4] + b[6] + b[9] + b[13]) { return; } for (int j = 0; j < c.length; j++) { System.out.print(j==0 ? "" : " "); System.out.print(b[j]); } return; } if (!c[i]) { for (int j = 0; j < a.length; j++) { if (!d[j]) { d[j] = true; c[i] = true; b[i] = a[j]; f(i + 1); c[i] = false; d[j] = false; } } } else { f(i + 1); } } }