.标题: 世纪末的星期
曾有邪教称1999年12月31日是世界末日。当然该谣言已经不攻自破。
还有人称今后的某个世纪末的12月31日,如果是星期一则会....
有趣的是,任何一个世纪末的年份的12月31日都不可能是星期一!!
于是,“谣言制造商”又修改为星期日......
1999年的12月31日是星期五,请问:未来哪一个离我们最近的一个世纪末年(即xx99年)的12月31日正好是星期天(即星期日)?
请回答该年份(只写这个4位整数,不要写12月31等多余信息)
2299,Calender类可用于1970年以后的日期操作
Java中Calendar类的常用方法https://blog.csdn.net/yx0628/article/details/79317440
public class _01_世纪末的星期 { public static void main(String[] args) { Calendar calendar = Calendar.getInstance();//可用于1970年后操作日期用 for (int year = 1999; year < 10000; year+=100) { calendar.set(Calendar.YEAR,year); calendar.set(Calendar.MONTH,11);//12月 只有月份是0开始的,0对应1月 calendar.set(Calendar.DAY_OF_MONTH,31); System.out.println(year+" "+calendar.get(Calendar.DAY_OF_WEEK)); if(calendar.get(Calendar.DAY_OF_WEEK)==1){//1:星期天 2:星期一 外国人的第一天是星期天 break; } } } } 下面这个特别暴力的代码不只适合1970以后的日子,考点闰年判断
import java.util.Scanner; public class _01_世纪末的星期1 { public static void main(String[] args) { Scanner in = new Scanner(System.in); int year = 1999; int week = 4;//为了方便求模,0代表星期一,1999年12月31是星期五,初始化4 // int[] data1 = new int[] {-1,31,28,31,30,31,30,31,31,30,31,30,31}; // int[] data2 = new int[] {-1,31,29,31,30,31,30,31,31,30,31,30,31};//闰年天数 for(year=2000;year public static void main(String[] args) { Scanner in = new Scanner(System.in); int ans=0; for(int a=1;a if(c==a || c==b) continue; for(int d=1;d if(e==a || e==b || e==c || e==d) continue; if((10*a+b)*(100*c+10*d+e)==(100*a+10*d+b)*(10*c+e))//ab * cde = adb * ce ans++; } } } } System.out.println(ans); } }
3.标题: 振兴中华
小明参加了学校的趣味运动会,其中的一个项目是:跳格子。
地上画着一些格子,每个格子里写一个字,如下所示:(也可参见p1.jpg)
从我做起振 我做起振兴 做起振兴中 起振兴中华
比赛时,先站在左上角的写着“从”字的格子里,可以横向或纵向跳到相邻的格子里,但不能跳到对角的格子或其它位置。一直要跳到“华”字结束。
要求跳过的路线刚好构成“从我做起振兴中华”这句话。
请你帮助小明算一算他一共有多少种可能的跳跃路线呢?
答案是一个整数,请通过浏览器直接提交该数字。 注意:不要提交解答过程,或其它辅助说明类的内容。
35,dp,递归都可以,leetcode 62. 不同路径(Unique Paths)
import java.util.Scanner; public class _03_振兴中华 { public static void main(String[] args) { Scanner in = new Scanner(System.in); int[][] dp = new int[15][15]; for(int i=1;i public static void main(String[] args) { BigInteger a=BigInteger.ONE; BigInteger b=BigInteger.ONE; //斐波那契数列的迭代形式 for (int i = 3; i < 500; i++) { BigInteger t=b; b=a.add(b);//大整数的加法 a=t; } //大浮点数的除法 BigDecimal divide = new BigDecimal(a,110).divide(new BigDecimal(b,110), BigDecimal.ROUND_HALF_DOWN); //截取字符串 System.out.println(divide.toPlainString().substring(0,103)); } } //0.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911375
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);
请分析代码逻辑,并推测划线处的代码,通过网页提交 注意:仅把缺少的代码作为答案,千万不要填写多余的代码、符号或说明文字!!
数学通分:a/b + c/d = (a*d+b*c)/(b*d)
new Rational(ra*x.rb+rb*x.ra, rb*x.rb) new Rational(this.ra * x.rb + x.ra * this.rb, this.rb * x.rb) 上面的答案都行,不要this是观察到乘法函数也没写
6.标题:三部排序
一般的排序有许多经典算法,如快速排序、希尔排序等。
但实际应用时,经常会或多或少有一些特殊的要求。我们没必要套用那些经典算法,可以根据实际情况建立更好的解法。
比如,对一个整型数组中的数字进行分类排序:
使得负数都靠左端,正数都靠右端,0在中部。注意问题的特点是:负数区域和正数区域内并不要求有序。可以利用这个特点通过1次线性扫描就结束战斗!!
以下的程序实现了该目标。
static void sort(int[] x) { int p = 0; int left = 0; int right = x.length-1; while(p int t = x[left]; x[left] = x[p]; x[p] = t; left++; p++; } else if(x[p]>0){ int t = x[right]; x[right] = x[p]; x[p] = t; right--; } else{ _________________________; //代码填空位置 } } } 如果给定数组: 25,18,-2,0,16,-5,33,21,0,19,-16,25,-3,0 则排序后为: -3,-2,-16,-5,0,0,0,21,19,33,25,16,18,25
请分析代码逻辑,并推测划线处的代码,通过网页提交 注意:仅把缺少的代码作为答案,千万不要填写多余的代码、符号或说明文字!!
答案:p++,快排思想,可以了解下三路快排,检验答案的时候吧代码复制运行一下就好,样例可以自己弄,也可以用给的
7.标题:错误票据
某涉密单位下发了某种票据,并要在年终全部收回。
每张票据有唯一的ID号。全年所有票据的ID号是连续的,但ID的开始数码是随机选定的。
因为工作人员疏忽,在录入ID号的时候发生了一处错误,造成了某个ID断号,另外一个ID重号。
你的任务是通过编程,找出断号的ID和重号的ID。
假设断号不可能发生在最大和最小号。
要求程序首先输入一个整数N(N Scanner in = new Scanner(System.in); ArrayList list = new ArrayList(); in.next();//n没什么用 while(in.hasNext()) { int x = in.nextInt(); if(x==-1)//仅仅方便自己检查,没用 break; list.add(x); } int x=0,y=0; Collections.sort(list); for(int i=0;i y = list.get(i); list.remove(i); break; } } int start = list.get(0); for(int i:list) { if(start!=i) { System.out.println(start+" "+y); break; }else start++; } } } import java.util.ArrayList; import java.util.Collections; import java.util.Scanner; public class _07_错误票据 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); ArrayList list = new ArrayList(); int N = sc.nextInt(); sc.nextLine();//吃掉整数后面的换行符 for (int i = 0; i < N; i++) { String line = sc.nextLine(); String[] split = line.split(" "); for (int j = 0; j < split.length; j++) { list.add(Integer.parseInt(split[j])); } } // System.out.println(list.size()); Collections.sort(list); int a = 0, b = 0; for (int i = 1; i < list.size(); i++) { if (list.get(i) - list.get(i - 1) == 2) a = list.get(i) - 1; if (list.get(i) - list.get(i - 1) == 0)//注意此处有坑,不能用== b = list.get(i); } System.out.println(a + " " + b); } }
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,否则按无效代码处理。
蓝桥杯的数据很神奇,自己说的100W,可我自测的时候10W也有点勉强了,很暴力的模拟AC代码,个人认为它给的数据规模会比它说的会小,看了源样例最多到1W5,呵呵了,另外3个样例最多是300,也就是超级无敌的暴力都能拿75%的分
import java.util.Arrays; import java.util.Scanner; public class _08幸运数1 { public static void main(String[] args) { Scanner in = new Scanner(System.in); int m = in.nextInt(); int n = in.nextInt(); int[] a = new int[n+1]; for(int i=1;i t = j; break; } } int ans = 0; for(int i=1;i public static void main(String[] args) { Scanner in = new Scanner(System.in); x = in.nextInt(); dfs(0); System.out.println(ans); } static int ans = 0,n = 9,x; static int A[] = new int[] {1,2,3,4,5,6,7,8,9}; static void dfs(int m) { if(m>=9) { for(int i=1;i swap(i,m); dfs(m+1); swap(i,m); } } private static void swap(int i, int j) { int t = A[i]; A[i] = A[j]; A[j] = t; } }
10.标题:连号区间数
小明这些天一直在思考这样一个奇怪而有趣的问题:
在1~N的某个全排列中有多少个连号区间呢?这里所说的连号区间的定义是:
如果区间[L, R] 里的所有元素(即此排列的第L个到第R个元素)递增排序后能得到一个长度为R-L+1的“连续”数列,则称这个区间连号区间。
当N很小的时候,小明可以很快地算出答案,但是当N变大的时候,问题就不是那么简单了,现在小明需要你的帮助。
输入格式: 第一行是一个正整数N (1 int max=-1,min=999999999; for(int j=i;j static int ans=0; static int vis[]=new int[10]; static int a[] =new int[9]; static int n; static void dfs(int num) { if(num==9) { if(check(a)) { ans++; } return; } for (int i = 1; i vis[i]=1; a[num]=i; dfs(num+1); a[num]=0; vis[i]=0; } } } private static boolean check(int[] arr) { for (int i =1; i n) break; //获取第二个数的元素 for (int j =1; j int ans=0; for (int i =pos; i public static void main(String[] args) { Scanner sc = new Scanner(System.in); int m=sc.nextInt(); int n=sc.nextInt(); int lucky=2,index=0,lucky_count=0;//lucky取2,为了忽略1 ArrayList list=new ArrayList(); ArrayList list_r=new ArrayList(); for(int i=1;i for (int i =1; i list_r.add(list.get(i-1)); } } index++; list.removeAll(list_r); if(index>=list.size()) { break; } lucky=list.get(index); } for(int i=1;i lucky_count++; } } System.out.println(lucky_count); } }
1.标题:武功秘籍
小明到X山洞探险,捡到一本有破损的武功秘籍(2000多页!当然是伪造的)。他注意到:书的第10页和第11页在同一张纸上,但第11页和第12页不在同一张纸上。
小明只想练习该书的第81页到第92页的武功,又不想带着整本书。请问他至少要撕下多少张纸带走?
这是个整数,请通过浏览器提交该数字,不要填写任何多余的内容。
7,(80,81),(82,83),(84,85),(86,87),(88,89),(90,91),(91,92)
题目告诉你2000多页,10-11连在一起,说明没过对称轴,就好数了,如果告诉你10和2000一页呢?
2.标题:切面条
一根高筋拉面,中间切一刀,可以得到2根面条。
如果先对折1次,中间切一刀,可以得到3根面条。
如果连续对折2次,中间切一刀,可以得到5根面条。
那么,连续对折10次,中间切一刀,会得到多少面条呢?
答案是个整数,请通过浏览器提交答案。不要填写任何多余的内容。
1025,脑补了一下,二分有关,猜下公式2^n+1,再推下n=3的情况,就差不多了
3.标题:猜字母
把abcd...s共19个字母组成的序列重复拼接106次,得到长度为2014的串。
接下来删除第1个字母(即开头的字母a),以及第3个,第5个等所有奇数位置的字母。
得到的新串再进行删除奇数位置字母的动作。如此下去,最后只剩下一个字母,请写出该字母。
答案是一个小写字母,请通过浏览器提交答案。不要填写任何多余的内容。
按照它说的做就好,不过我26个字母不会排,好在有ASCII码,答案:q
String会内存溢出,用StringBuilder,StringBuilder的好处就是修改多次有优势,百度下
public class 猜字母 { public static void main(String[] args) { //abcdefghijklmnopqrs StringBuilder s = new StringBuilder("abcdefghijklmnopqrs"); for(int i=1;i1) { System.out.println(s.length()); StringBuilder s1 = new StringBuilder(); for(int i=1;i ss+=s; //拼接106次 } while(ss.size()>1){ //判断循环结束 for(int i=0;i if(________________) //填空 System.out.println(i*i/2); else System.out.println((i*i-1)/2); } 请填写划线部分缺失的代码。通过浏览器提交答案。
注意:不要填写题面已有的内容,也不要填写任何说明、解释文字。
i%2==0
5.标题:圆周率
数学发展历史上,圆周率的计算曾有许多有趣甚至是传奇的故事。其中许多方法都涉及无穷级数。
图1.png中所示,就是一种用连分数的形式表示的圆周率求法。
下面的程序实现了该求解方法。实际上数列的收敛对x的初始值 并不敏感。
结果打印出圆周率近似值(保留小数点后4位,并不一定与圆周率真值吻合)。
double x = 111; for(int n = 10000; n>=0; n--){ int i = 2 * n + 1; x = 2 + (i*i / x); } System.out.println(String.format("%.4f", ______________));
4.0/(x-1)
6.标题:奇怪的分式
上小学的时候,小明经常自己发明新算法。一次,老师出的题目是:
1/4 乘以 8/5
小明居然把分子拼接在一起,分母拼接在一起,答案是:18/45 (参见图1.png)
老师刚想批评他,转念一想,这个答案凑巧也对啊,真是见鬼!
对于分子、分母都是 1~9 中的一位数的情况,还有哪些算式可以这样计算呢?
请写出所有不同算式的个数(包括题中举例的)。
显然,交换分子分母后,例如:4/1 乘以 5/8 是满足要求的,这算做不同的算式。
但对于分子分母相同的情况,2/2 乘以 3/3 这样的类型太多了,不在计数之列!
注意:答案是个整数(考虑对称性,肯定是偶数)。请通过浏览器提交。不要书写多余的内容。
14,暴力4个for 打印验证
public class _06奇怪的分式 { public static void main(String[] args) { // A/B x C/D = E/F A*C*F = E*B*D int ans=0; for(int a=1;a ans++; System.out.println(a+"/"+b+" x "+c+"/"+d+" = "+e+"/"+f+" "+ans); } } } }
7.标题:扑克序列
A A 2 2 3 3 4 4, 一共4对扑克牌。请你把它们排成一行。 要求:两个A中间有1张牌,两个2之间有2张牌,两个3之间有3张牌,两个4之间有4张牌。
请填写出所有符合要求的排列中,字典序最小的那个。
例如:22AA3344 比 A2A23344 字典序小。当然,它们都不是满足要求的答案。
请通过浏览器提交答案。“A”一定不要用小写字母a,也不要用“1”代替。字符间一定不要留空格。
2342A3A4,又是一道全排,因为A是比2大的那么把A看成5就好
public class _07扑克序列1 { public static void main(String[] args) { dfs(0); } static int[] a = new int[] {5,5,2,2,3,3,4,4}; static void dfs(int m) { if(m>=8) { int A1=-1,A2=-1,B1=-1,B2=-1,C1=-1,C2=-1,D1=-1,D2=-1; for(int i=0;i if(B1==-1) B1 = i; else B2 = i; }else if(a[i]==3) { if(C1==-1) C1 = i; else C2 = i; }else if(a[i]==4) { if(D1==-1) D1 = i; else D2 = i; } if(A2-A1!=2 || B2-A1!=3 || C2-C1!=4 || D2-D1!=5) return; for(int i=0;i int t = a[i]; a[i] = a[j]; a[j] = t; } } 8.标题:分糖果
有n个小朋友围坐成一圈。老师给每个小朋友随机发偶数个糖果,然后进行下面的游戏:
每个小朋友都把自己的糖果分一半给左手边的孩子。
一轮分糖后,拥有奇数颗糖的孩子由老师补给1个糖果,从而变成偶数。
反复进行这个游戏,直到所有小朋友的糖果数都相同为止。
你的任务是预测在已知的初始糖果情形下,老师一共需要补发多少个糖果。
【格式要求】
程序首先读入一个整数N(2 Scanner in = new Scanner(System.in); int n = in.nextInt(); int[] a = new int[n]; int[] b = new int[n]; int ans=0; for(int i=0;i a[i] = a[i]/2 + b[(i+1)%n]; if(a[i]%2==1) { ans++; a[i]++; } } for(int i=1;i public static void main(String[] args) { Scanner in = new Scanner(System.in); n = in.nextInt(); m = in.nextInt(); k = in.nextInt(); a = new int[n+5][m+5]; int max=0; for(int i=0;i if(memo[x][y][now][max]!=-1) return memo[x][y][now][max]; if(x==0 && y==0) { if(now==0) return 1; if(now==1 && max>a[x][y]) return 1; return 0; } memo[x][y][now][max] = 0; if(now>0) { if(x>0) { memo[x][y][now][max] = (memo[x][y][now][max]+f(x-1,y,now,max))%1000000007; if(max>a[x][y]) memo[x][y][now][max] = (memo[x][y][now][max]+f(x-1,y,now-1,a[x][y]))%1000000007; } if(y>0) { memo[x][y][now][max] = (memo[x][y][now][max]+f(x,y-1,now,max))%1000000007; if(max>a[x][y]) memo[x][y][now][max] = (memo[x][y][now][max]+f(x,y-1,now-1,a[x][y]))%1000000007; } } else { if(x>0) memo[x][y][now][max] = (memo[x][y][now][max]+f(x-1,y,now,max))%1000000007; if(y>0) memo[x][y][now][max] = (memo[x][y][now][max]+f(x,y-1,now,max))%1000000007; } return memo[x][y][now][max]%1000000007; } }
10.标题:矩阵翻硬币
小明先把硬币摆成了一个 n 行 m 列的矩阵。
随后,小明对每一个硬币分别进行一次 Q 操作。
对第x行第y列的硬币进行 Q 操作的定义:将所有第 i*x 行,第 j*y 列的硬币进行翻转。
其中i和j为任意使操作可行的正整数,行号和列号都是从1开始。
当小明对所有硬币都进行了一次 Q 操作后,他发现了一个奇迹——所有硬币均为正面朝上。
小明想知道最开始有多少枚硬币是反面朝上的。于是,他向他的好朋友小M寻求帮助。
聪明的小M告诉小明,只需要对所有硬币再进行一次Q操作,即可恢复到最开始的状态。然而小明很懒,不愿意照做。于是小明希望你给出他更好的方法。帮他计算出答案。
【数据格式】 输入数据包含一行,两个正整数 n m,含义见题目描述。 输出一个正整数,表示最开始有多少枚硬币是反面朝上的。
【样例输入】 2 3
【样例输出】 1
【数据规模】 对于10%的数据,n、m int length = s.length(); int len = 0; if (length % 2 == 0) len = length / 2; else len = length / 2 + 1; char[] sArr = new char[len]; Arrays.fill(sArr, '0'); BigInteger target = new BigInteger(s); for (int pos = 0; pos < len; pos++) { for (char c = '1'; c sArr[pos] -= 1; break; } } } return new BigInteger(String.valueOf(sArr)); } }
小结:
01 武功秘籍 书的构造方式,思维题 02 切面条 发现规律,思维题 03 猜字母 数组中元素的挪动和挤压 04 大衍数列 考察奇偶数判断 05 圆周率 细心,极限思维 06 奇怪的分式 枚举abcd,分数运算,最大公约数 07 扑克排序 带重复元素的全排列 08 分糖果 模拟 **09 地宫取宝 搜索->记忆型递归,因为子问题重复求解 ****10 矩阵翻硬币 数学;字符,字符串,BigInteger的互相转化
1.三角形面积
如图1所示。图中的所有小方格面积都是1。 那么,图中的三角形面积应该是多少呢?
请填写三角形的面积。不要填写任何多余内容或说明性文字。
思路:矩形减去3个三角形面积 8*8 - 0.5*8*4 - 0.5*4*6 - 0.5*8*2 答案:28
2.立方变自身
观察下面的现象,某个数字的立方,按位累加仍然等于自身。 1^3 = 1 8^3 = 512 5+1+2=8 17^3 = 4913 4+9+1+3=17 ...
请你计算包括1,8,17在内,符合这个性质的正整数一共有多少个?
请填写该数字,不要填写任何多余的内容或说明性的文字。
答案:6,暴力枚举1到10000,打印观察,发现最大的数只是到27,没必要再扩大枚举的范围了,6已是答案
public class _02立方变自身1 { public static void main(String[] args) { int ans = 0; for(int i=1;i System.out.println(":"+i); ans++; } } System.out.println(ans); } static int f(int x) { int ans=0; while(x>0) { ans+=x%10; x/=10; } return ans; } } 3.三羊献瑞
观察下面的加法算式:
祥 瑞 生 辉 + 三 羊 献 瑞 ------------------- 三 羊 生 瑞 气
(如果有对齐问题,可以参看【图1.jpg】)
其中,相同的汉字代表相同的数字,不同的汉字代表不同的数字。
请你填写“三羊献瑞”所代表的4位数字(答案唯一),不要填写任何多余内容。
这种0-9不同数字的枚举,直接暴力就好,不过感觉暴力也要写挺久的,也可以试下全排,答案:1085
public class _03三羊献瑞_ { public static void main(String[] args) { for(int x1=0;x1 if(x3==x1 || x3==x2) continue; for(int x4=0;x4 if(x5==x1 || x5==x2 || x5==x3 || x5==x4) continue; for(int x6=0;x6 if(x7==x1 || x7==x2 || x7==x3 || x7==x4 || x7==x5 || x7==x6) continue; for(int x8=0;x8 System.out.println(x+"+"+y+"=="+z); System.out.println(x1+" "+x2+" "+x3+" "+x4+" "+x5+" "+x6+" "+x7+" "+x8+" "); } } } } } } } } } } 全排的话直接截取前8个数就好,写起来比上面8个for要舒爽,不过直觉上感觉8个for稳一点org
public class _03三羊献瑞_全排 { public static void main(String[] args) { dfs(0); } static int[] a = new int [] {0,1,2,3,4,5,6,7,8,9}; static void dfs(int m) { if(m>=10) { int x = 1000*a[0] + 100*a[1] + 10*a[2] + a[3]; int y = 1000*a[4] + 100*a[5] + 10*a[6] + a[1]; int z = 10000*a[4] + 1000*a[5] + 100*a[2] + 10*a[1] + a[7]; if(a[0]==0 || a[4]==0) return; if(x+y==z) System.out.println(x+"+"+y+"=="+z); return; } for(int i=m;i int t = a[i]; a[i] = a[j]; a[j] = t; } }
4.循环节长度
两个整数做除法,有时会产生循环小数,其循环部分称为:循环节。 比如,11/13=6=>0.846153846153..... 其循环节为[846153] 共有6位。 下面的方法,可以求出循环节的长度。
请仔细阅读代码,并填写划线部分缺少的代码。
public static int f(int n, int m) { n = n % m; Vector v = new Vector(); for(;;) { v.add(n); n *= 10; n = n % m; if(n==0) return 0; if(v.indexOf(n)>=0) _________________________________ ; //填空 } } 注意,只能填写缺少的部分,不要重复抄写已有代码。不要填写任何多余的文字。
return v.size() - v.indexOf(n);差点没看到v.add(),这里直接填v.size()是不对的比如7/18 0.3888888 但他会输出2,而应该是1,所以要减去第一个重复字母的下标
5.九数组分数
1,2,3...9 这九个数字组成一个分数,其值恰好为1/3,如何组法?
下面的程序实现了该功能,请填写划线部分缺失的代码。
public class A { public static void test(int[] x) { int a = x[0]*1000 + x[1]*100 + x[2]*10 + x[3]; int b = x[4]*10000 + x[5]*1000 + x[6]*100 + x[7]*10 + x[8]; if(a*3==b) System.out.println(a + " " + b); } public static void f(int[] x, int k) { if(k>=x.length){ test(x); return; } for(int i=k; i int[] x = {1,2,3,4,5,6,7,8,9}; f(x,0); } } 注意,只能填写缺少的部分,不要重复抄写已有代码。不要填写任何多余的文字。
答案:{int t=x[k]; x[k]=x[i]; x[i]=t;},全排,回溯
6.加法变乘法
我们都知道:1+2+3+ ... + 49 = 1225 现在要求你把其中两个不相邻的加号变成乘号,使得结果为2015
比如: 1+2+3+...+10*11+12+...+27*28+29+...+49 = 2015 就是符合要求的答案。
请你寻找另外一个可能的答案,并把位置靠前的那个乘号左边的数字提交(对于示例,就是提交10)。
注意:需要你提交的是一个整数,不要填写任何多余的内容。
答案:16,看错题目了,还想用下前缀和,这里模拟,先减去这4个改变的数,再加入2个乘积的结果
public class _06__加法变乘法 { public static void main(String[] args) { int[] sum = new int[50]; for(int i=1;i int sum=0; for(int a=0; a public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); System.out.println(n+f(n)); } static int f(int n) { if(n Scanner in = new Scanner(System.in); for(int i=0;i if(x init(); Scanner sc = new Scanner(System.in); n = sc.nextInt(); m = sc.nextInt(); long conflict[][] = new long[6][6]; for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { conflict[i][j]=1; } } //建立冲突矩阵 for (int i = 0; i < m; i++) { int a = sc.nextInt(); int b = sc.nextInt(); conflict[op[a] - 1][b - 1] = 0; conflict[op[b] - 1][a - 1] = 0; } // 求冲突矩阵的n-1次方 long[][] mPow_n_1 = mPow(conflict, n - 1); //累加矩阵的每个元素 long ans = 0; for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { ans = (ans + mPow_n_1[i][j]) % MOD; } } //ans*4^n System.out.println(ans * power(4, n) % MOD); } private static long power(long i, int n) { long ans = 1; while (n != 0) { if ((n & 1) == 1) ans = (ans * i) % MOD; i = i * i % MOD; n >>= 1; } return ans; } /*矩阵的快速幂*/ private static long[][] mPow(long[][] conflict, int n) { long[][] e = new long[6][6]; for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { if (i == j) e[i][j] = 1; else e[i][j] = 0; } } while (n != 0) { if ((n & 1) == 1) { e = mMul(e, conflict); } conflict = mMul(conflict, conflict); n >>= 1; } return e; } private static long[][] mMul(long[][] a, long[][] b) { long[][] ans = new long[6][6]; for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { for (int k = 0; k < 6; k++) { ans[i][j] = (ans[i][j] + a[i][k] * b[k][j]) % MOD; } } } return ans; } }
10.生命之树
在X森林里,上帝创建了生命之树。
他给每棵树的每个节点(叶子也称为一个节点)上,都标了一个整数,代表这个点的和谐值。 上帝要在这棵树内选出一个非空节点集S,使得对于S中的任意两个点a,b,都存在一个点列 {a, v1, v2, ..., vk, b} 使得这个点列中的每个点都是S里面的元素,且序列中相邻两个点间有一条边相连。
在这个前提下,上帝要使得S中的点所对应的整数的和尽量大。 这个最大的和就是上帝给生命之树的评分。
经过atm的努力,他已经知道了上帝给每棵树上每个节点上的整数。但是由于 atm 不擅长计算,他不知道怎样有效的求评分。他需要你为他写一个程序来计算一棵树的分数。
「输入格式」 第一行一个整数 n 表示这棵树有 n 个节点。 第二行 n 个整数,依次表示每个节点的评分。 接下来 n-1 行,每行 2 个整数 u, v,表示存在一条 u 到 v 的边。由于这是一棵树,所以是不存在环的。
「输出格式」 输出一行一个数,表示上帝给这棵树的分数。
「样例输入」 5 1 -2 -3 4 5 4 2 3 1 1 2 2 5
「样例输出」 8
「数据范围」 对于 30% 的数据,n System.setIn(new FileInputStream(new File("/Users/zhengwei/workspace/lanqiaobei2019/src/2015_Java_B/data10/in5.txt"))); Scanner sc = new Scanner(System.in); n = sc.nextInt(); w = new long[n + 1]; g = new ArrayList[n + 1]; initG(); for (int i = 1; i int a = sc.nextInt(); int b = sc.nextInt(); g[a].add(b); g[b].add(a); } dfs(1, 0); System.out.println(ans); } /** * u做为根所代表的子树有一个最大权和,将其存储在w[u]中 * @param u * @param fa */ private static void dfs(int u, int fa) { for (int i = 0; i < g[u].size(); i++) { Integer child = g[u].get(i); if (child == fa) continue; dfs(child, u); if (w[child] > 0) w[u] += w[child]; } if (w[u] > ans) ans = w[u]; } private static void initG() { for (int i = 0; i < n + 1; i++) { g[i] = new ArrayList(); } } }
小结:
01 三角形面积 热身 不用编程 02 立方变自身 简单枚举 03 三羊献瑞 简单枚举 小技巧 *04 循环节长度 有坑 逻辑 05 九数组分数 全排列 带分数 06 加法变乘法 简单枚举 小技巧 07 牌型种数 递归 08 饮料换购 模拟 ****09 垒骰子 递归-动规-矩阵快速幂 *****10 生命之树 Java中递归最多1万层
文章知识点与官方知识档案匹配,可进一步学习相关知识 算法技能树蓝桥杯-简单第几天5290 人正在系统学习中
一叶之修 关注
14
3
16
专栏目录 2015年蓝桥杯省赛B组C/C++(试题+答案分析) weixin_44683914的博客 1206 2015年蓝桥杯省赛B组C/C++(试题+答案分析) 第一题 结果填空 (3分) 奖券数目 有些人很迷信数字,比如带“4”的数字,认为和“死”谐音,就觉得不吉利。 虽然这些说法纯属无稽之谈,但有时还要迎合大众的需求。某抽奖活动的奖券号码是5位数(10000-99999),要求其中不要出现带“4”的号码,主办单位请你计算一下,如果任何两张奖券不重号,最多可发出奖券多少张。 请提交该数字(一个整数),... 蓝桥杯真题15省Ca8-饮料乐羊羊饮料厂正在举办一次促销优惠活动。乐羊羊C型饮料,凭3个瓶盖可以再换一瓶C型饮料,并且可以一直循环下去(但不允许暂借或赊账)。 请你计算一下,如果小明不浪费瓶盖, qq_45281807的博客 1121 问题描述 乐羊羊饮料厂正在举办一次促销优惠活动。乐羊羊C型饮料,凭3个瓶盖可以再换一瓶C型饮料,并且可以一直循环下去(但不允许暂借或赊账)。 请你计算一下,如果小明不浪费瓶盖,尽量地参加活动,那么,对于他初始买入的n瓶饮料,最后他一共能喝到多少瓶饮料。 输入 一个整数n,表示开始购买的饮料数量(0 Scanner sc = new Scanner(System.in); int n=sc.nextInt(); int ans=0; while(n>2) { ans+=3; n-=2; } ans=ans+n; System.out.println(ans); } }