文章目录
1. 标题: 世纪末的星期
同A组: JAVA蓝桥杯真题笔记(2013年A组)
2. 标题: 马虎的算式
小明是个急性子,上小学的时候经常把老师写在黑板上的题目抄错了。
有一次,老师出的题目是:36 x 495 = ?
他却给抄成了:396 x 45 = ?
但结果却很戏剧性,他的答案竟然是对的!!
因为 36 * 495 = 396 * 45 = 17820
类似这样的巧合情况可能还有很多,比如:27 * 594 = 297 * 54
假设 a b c d e 代表1~9不同的5个数字(注意是各不相同的数字,且不含0)
能满足形如: ab * cde = adb * ce 这样的算式一共有多少种呢?
请你利用计算机的优势寻找所有的可能,并回答不同算式的种类数。
满足乘法交换律的算式计为不同的种类,所以答案肯定是个偶数。
答案直接通过浏览器提交。
注意:只提交一个表示最终统计种类数的数字,不要提交解答过程或其它多余的内容。
满足乘法交换律的算式计为不同的种类,所以答案肯定是个偶数。
注意这句话的意思,27 * 594 = 297 * 54 和 54 * 297 = 594 * 27是两个不同的式子,可能会误导你在计算的结果上乘2,但是仔细考虑,此处不用乘2。
答案: 142
package B13;
public class Demo02 {
public static void main(String[] args) {
// ab * cde = adb * ce
int count = 0;
// 要保证a,b,c,d,e不重复
for (int a = 1; a < 10; a++) {
for (int b = 1; b < 10; b++) {
if (a == b){
// 保证a和b不相等
continue;
}
for (int c = 1; c < 10; c++) {
if (c==a || c==b){
// 保证a,b,c不相等
continue;
}
for (int d = 1; d < 10; d++) {
if (d==a || d == b || d == c){
// 保证a,b,c,d不相等
continue;
}
for (int e = 1; e < 10; e++) {
if (e == a || e == b || e == c || e == d){
// 保证a,b,c,d, e不相等
continue;
}
if ((a*10+b)*(c*100+d*10+e) == (a*100+d*10+b)*(c*10+e)){
count++;
}
}
}
}
}
}
System.out.println(count);
}
}
3. 标题: 振兴中华
同A组: JAVA蓝桥杯真题笔记(2013年A组) 第二题
4. 标题: 黄金连分数
黄金分割数0.61803… 是个无理数,这个常数十分重要,在许多工程问题中会出现。
有时需要把这个数字求得很精确。
对于某些精密工程,常数的精度很重要。
也许你听说过哈勃太空望远镜,它首次升空后就发现了一处人工加工错误,
对那样一个庞然大物,其实只是镜面加工时有比头发丝还细许多倍的一处错误而已,
却使它成了“近视眼”!!
言归正传,我们如何求得黄金分割数的尽可能精确的值呢?有许多方法。
比较简单的一种是用连分数:
1
黄金数 = ---------------------
1
1 + -----------------
1
1 + -------------
1
1 + ---------
1 + ...
这个连分数计算的“层数”越多,它的值越接近黄金分割数。
请你利用这一特性,求出黄金分割数的足够精确值,要求四舍五入到小数点后100位。
小数点后3位的值为:0.618
小数点后4位的值为:0.6180
小数点后5位的值为:0.61803
小数点后7位的值为:0.6180340
(注意尾部的0,不能忽略)
你的任务是:写出精确到小数点后100位精度的黄金分割值。
注意:尾数的四舍五入! 尾数是0也要保留!
显然答案是一个小数,其小数点后有100位数字,请通过浏览器直接提交该数字。
注意:不要提交解答过程,或其它辅助说明类的内容。
1. 化为求斐波那契相邻两项的比值,求多少项? 当 n/n+1再中的n再往上增时,这个比值小数点后101位是稳定的,此时可以取小数点后100项
2. double无法满足表示100位小数,用BigInteger和BigDecimal
package B13;
import java.math.BigDecimal;
public class Demo04 {
public static void main(String[] args) {
BigDecimal a = BigDecimal.ONE;
BigDecimal b = BigDecimal.ONE;
BigDecimal t;
for (int i = 0; i < 400; i++) {
t = b;
b = a.add(b);
a = t;
}
// System.out.println(a.divide(b, 101, BigDecimal.ROUND_HALF_UP));
System.out.println(a.divide(b, 100, BigDecimal.ROUND_HALF_UP));
// 0.61803398874989484820458683436563811772030969980941182649362912941520163540937291916173851894971905630
// 0.61803398874989484820458683436563811772030917980576286213544862270526046281890244970803605876859146255
// 0.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748
// 0.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748
// 0.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911375
}
}
a.divide(b, 100, BigDecimal.ROUND_HALF_UP) 中的第二个参数代表小数点后精确到的尾数,第三个参数是指用四舍五入方式精确
5. 标题: 有理数类
问题描述
有理数就是可以表示为两个整数的比值的数字。一般情况下,我们用近似的小数表示。
但有些时候,不允许出现误差,必须用两个整数来表示一个有理数。
这时,我们可以建立一个“有理数类”,下面的代码初步实现了这个目标。为了简明,
它只提供了加法和乘法运算。
class Rational
{
private long ra;
private long rb;
private long gcd(long a, long b){
if(b==0) return a;
return gcd(b,a%b);
}
public Rational(long a, long b){
ra = a;
rb = b;
long k = gcd(ra,rb);
if(k>1){
//需要约分
ra /= k;
rb /= k;
}
}
// 加法
public Rational add(Rational x){
return ________________________________________; //填空位置
}
// 乘法
public Rational mul(Rational x){
return new Rational(ra*x.ra, rb*x.rb);
}
public String toString(){
if(rb==1) return "" + ra;
return ra + "/" + rb;
}
}
使用该类的示例:
Rational a = new Rational(1,3);
Rational b = new Rational(1,6);
Rational c = a.add(b);
System.out.println(a + “+” + b + “=” + c);
请分析代码逻辑,并推测划线处的代码,通过网页提交。
注意:仅把缺少的代码作为答案,千万不要填写多余的代码、符号或说明文字!!
new Rational(ra * x.rb + x.ra * rb, rb * x.rb) // 填空位置
6. 标题: 三部排序
同A组: JAVA蓝桥杯真题笔记(2013年A组) 第5题
7. 标题: 错误票据
同A组: JAVA蓝桥杯真题笔记(2013年A组) 第7题
8. 标题: 幸运数
问题描述
幸运数是波兰数学家乌拉姆命名的。它采用与生成素数类似的“筛法”生成。
首先从1开始写出自然数1,2,3,4,5,6,…
1 就是第一个幸运数。
我们从2这个数开始。把所有序号能被2整除的项删除,变为:
1 _ 3 _ 5 _ 7 _ 9 …
把它们缩紧,重新记序,为:
1 3 5 7 9 … 。这时,3为第2个幸运数,然后把所有能被3整除的序号位置的数删去。注意,是序号位置,不是那个数本身能否被3整除!! 删除的应该是5,11, 17, …
此时7为第3个幸运数,然后再删去序号位置能被7整除的(19,39,…)
最后剩下的序列类似:
1, 3, 7, 9, 13, 15, 21, 25, 31, 33,
37, 43, 49, 51, 63, 67, 69, 73, 75, 79, …
本题要求:
输入两个正整数m n, 用空格分开 (m < n < 1000*1000)
程序输出 位于m和n之间的幸运数的个数(不包含m和n)。
例如:
用户输入:
1 20
程序输出:
5
例如:
用户输入:
30 69
程序输出:
8
资源约定:
峰值内存消耗(含虚拟机) < 64M
CPU消耗 < 2000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
暴搜 + 优化
可以将偶数去除掉,默认从3为幸运数开始搜索
初始化数组时将0位置占位,不进行初始化,保证 下标=位置,遍历数组,从幸运数的后面位置开始,删除幸运数倍数位置的数(将后面的数挪前来覆盖要删除位置的数),当搜索时碰到第一个大于等于n的数时,可提前终止循环,重复删除过程,当幸运数大于等于n时,可结束程序,然后统计区间的幸运数。(注意每次最新的幸运数的位置发送变化 L++)
难点在于覆盖坑位和优化
package B13;
import java.util.Scanner;
/*
首先从1开始写出自然数1,2,3,4,5,6,....
1 就是第一个幸运数。
我们从2这个数开始。把所有序号能被2整除的项删除,变为:
1 _ 3 _ 5 _ 7 _ 9 ....
把它们缩紧,重新记序,为:
1 3 5 7 9 .... 。这时,3为第2个幸运数,然后把所有能被3整除的序号位置的数删去。注意,是序号位置,不是那个数本身能否被3整除!! 删除的应该是5,11, 17, ...
此时7为第3个幸运数,然后再删去序号位置能被7整除的(19,39,...)
最后剩下的序列类似:
1, 3, 7, 9, 13, 15, 21, 25, 31, 33,
37, 43, 49, 51, 63, 67, 69, 73, 75, 79, ...
*/
public class Demo08 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int m = scan.nextInt();
int n = scan.nextInt();
int[] a = new int[n+1]; // 0位置空出来
for (int i = 1; i <= n; i++) {
// 默认去除偶数项
a[i] = i * 2 - 1;
}
int l = 2; // 记录每一轮的幸运数的下标
while (true){
int p = l + 1; // p用来记录真实的位置
for (int i = l + 1; i <= n; i++) {
if (a[i] >= n) break;
if (i % a[l] == 0){
}
else {
a[p] = a[i];
p++;
}
}
l++; // 改变幸运数的位置
if(a[l]*2 >= n) break; // 如果在n范围内已经没有幸运数的倍数,则跳出循环
// for (int i = 1; i <= n; i++) {
// System.out.print(a[i] + " ");
// }
// System.out.println();
}
int ans = 0;
for (int i = 1; i <= n; i++) {
if (a[i] - a[i-1] <= 0) break;
if (a[i] > m) ans++;
}
System.out.println(ans);
}
}
9. 标题: 带分数
同A组: JAVA蓝桥杯真题笔记(2013年A组) 第8题
10. 标题: 连号区间数
问题描述
小明这些天一直在思考这样一个奇怪而有趣的问题:
在1~N的某个全排列中有多少个连号区间呢?这里所说的连号区间的定义是:
如果区间[L, R] 里的所有元素(即此排列的第L个到第R个元素)递增排序后能得到一个长度为R-L+1的“连续”数列,则称这个区间连号区间。
当N很小的时候,小明可以很快地算出答案,但是当N变大的时候,问题就不是那么简单了,现在小明需要你的帮助。
输入格式:
第一行是一个正整数N (1 <= N <= 50000), 表示全排列的规模。
第二行是N个不同的数字Pi(1 <= Pi <= N), 表示这N个数字的某一全排列。
输出格式:
输出一个整数,表示不同连号区间的数目。
示例:
用户输入:
4
3 2 4 1
程序应输出:
7
用户输入:
5
3 4 2 5 1
程序应输出:
9
解释:
第一个用例中,有7个连号区间分别是:[1,1], [1,2], [1,3], [1,4], [2,2], [3,3], [4,4]
第二个用例中,有9个连号区间分别是:[1,1], [1,2], [1,3], [1,4], [1,5], [2,2], [3,3], [4,4], [5,5]
资源约定:
峰值内存消耗(含虚拟机) < 64M
CPU消耗 < 5000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
一个区间内 max - min = right - left 时, 此区间连续,如: [7,10,9, 8] 中 max = 10,min = 7,right = 4,left = 1,此时10 - 7 = 4 - 1,所以连续
package B13;
import java.util.Scanner;
public class Demo10 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int[] a = new int[n + 1]; // 0位置空出来
for (int i = 1; i < n + 1; i++) {
a[i] = scan.nextInt();
}
int ans = 0;
int max;
int min;
for (int i = 1; i <= n; i++) {
max = a[i];
min = a[i];
for (int j = i; j <= n; j++) {
if (i==j) {
// [1, 1], [2, 2], [3, 3], [4, 4]......
ans++;
continue;
}
if (a[j] > max) max = a[j]; // 当前区间内的最大值
if (a[j] < min) min = a[j]; // 当前区间内的最小值
if (max - min == j - i) ans++;
}
}
System.out.println(ans);
}
}