第八届蓝桥杯真题解析javaC组
文章目录
- ***第八届蓝桥杯真题解析javaC组***
- 前言
- A、外星日历
- B.兴趣小组
- C.纸牌三角形
- D.承压计算
- E.杨辉三角
- F.最大公共子串
- G.Excel地址
- H.拉马车
- I.青蛙跳杯子
- J.图形排版
前言
以下是我做第八届蓝桥杯真题时的一些收获,希望对你们有帮助。
提示:以下是本篇文章正文内容,下面案例可供参考
A、外星日历
问题描述:
某星系深处发现了文明遗迹。
他们的计数也是用十进制。
他们的文明也有日历。日历只有天数,没有年、月的概念。
有趣的是,他们也使用了类似“星期”的概念,
只不过他们的一个星期包含了9天,
为了方便,这里分别记为: A,B,C…H,I
从一些资料上看到,
他们的23日是星期E
他们的190日是星期A
他们的343251日是星期I
令人兴奋的是,他们居然也预见了“世界末日”的那天,
当然是一个很大很大的数字
651764141421415346185
请你计算一下,这遥远的一天是该文明的星期几?
你需要提交的是一个大写字母,表示该文明的星期几,
不要填写任何多余的内容。
这道题和第十一届的第一题很相似,都是要使用到BigInteger类
代码如下(示例):
import java.math.BigInteger;
import java.util.Scanner;
public class Eight1_外星日历 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
char[] arr = {'I', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};
BigInteger nums = scanner.nextBigInteger();
scanner.close();
BigInteger mo = new BigInteger("9");
String yo = nums.mod(mo).toString();
System.out.println(arr[Integer.parseInt(yo)]);
}
}
B.兴趣小组
问题描述:
为丰富同学们的业余文化生活,某高校学生会创办了3个兴趣小组
(以下称A组,B组,C组)。
每个小组的学生名单分别在【A.txt】,【B.txt】和【C.txt】中。
每个文件中存储的是学生的学号。
由于工作需要,我们现在想知道:
既参加了A组,又参加了B组,但是没有参加C组的同学一共有多少人?
请你统计该数字并通过浏览器提交答案。
注意:答案是一个整数,不要提交任何多余的内容。
笨笨有话说:
哇塞!数字好多啊!一眼望过去就能发现相同的,好像没什么指望。
不过,可以排序啊,要是每个文件都是有序的,那就好多了。
歪歪有话说:
排什么序啊,这么几行数字对计算机不是太轻松了吗?
我看着需求怎么和中学学过的集合很像啊…
这道题似乎没有什么特殊的方法,就是直接暴力破解即可。
代码如下(示例):
public class Eight2_兴趣小组 {
static int flag;
public static void main(String[] args) {
//A组
int[] A = {
12894792, 92774113, 59529208, 22962224, 2991600, 83340521, 87365045,
40818286, 16400628, 39475245, 55933381, 76940287, 61366748, 95631228,
17102313, 50682833, 61562613, 87002524, 83062019, 51743442, 61977890,
32010762, 69680621, 87179571, 81761697, 32364296, 7833271, 36198035,
26588918, 84046668, 43059468, 73191775, 56794101, 454780, 11141030,
10008994, 35072237, 44945158, 53959980, 75758119, 18560273, 35801494,
42102550, 22496415, 3981786, 34593672, 13074905, 07733442, 42374678,
23452507, 98586743, 30771281, 17703080, 52123562, 5898131, 56698981,
90758589, 18238802, 18217979, 4511837, 75682969, 31135682, 55379006,
42224598, 98263070, 40228312, 28924663, 11580163, 25686441, 45944028,
96731602, 53675990, 3854194, 14858183, 16866794, 40677007, 73141512,
32317341, 56641725, 43123040, 15201174, 62389950, 72887083, 76860787,
61046319, 6923746, 17874548, 46028629, 10577743, 48747364, 5328780,
59855415, 60965266, 20592606, 14471207, 70896866, 46938647, 33575820,
53426294, 56093931, 51326542, 94050481, 80114017, 33010503, 72971538,
22407422, 17305672, 78974338, 93209260, 83461794, 41247821, 26118061,
10657376, 42198057, 15338224, 50284714, 32232841, 26716521, 76048344,
23676625, 62897700, 69296551, 59653393, 38704390, 48481614, 69782897,
26850668, 37471053, 88720989, 51010849, 94951571, 60024611, 29808329,
70377786, 13899299, 9683688, 58218284, 46792829, 97221709, 45286643,
48158629, 57367208, 26903401, 76900414, 87927040, 9926730, 1508757,
15101101, 62491840, 43802529,
};
//B组
int[] B = {
44894050, 34662733, 44141729, 92774113, 99208727, 91919833, 23727681,
10003409, 55933381, 54443275, 13584702, 96523685, 50682833, 61562613,
62380975, 20311684, 93200452, 23101945, 42192880, 28992561, 18460278,
19186537, 58465301, 01111066, 62680429, 23721241, 20277631, 91708977,
57514737, 3981786, 81541612, 07346443, 93154608, 19709455, 37446968,
17703080, 72378958, 66200696, 30610382, 89586343, 33152171, 67040930,
35696683, 63242065, 99948221, 96233367, 52593493, 98263070, 1418023,
74816705, 89375940, 58405334, 96731602, 84089545, 16866794, 94737626,
01673442, 70548494, 13638168, 8163691, 11106566, 64375392, 40267902,
897705, 56447313, 54532235, 94738425, 66642634, 83219544, 40546096,
66924991, 20592606, 96037590, 73434467, 70896866, 91025618, 57892091,
8487641, 32500082, 84412833, 23311447, 38380409, 79957822, 72971538,
69645784, 91863314, 73099909, 93209260, 83461794, 81378487, 30423273,
22233715, 32232841, 26716521, 03511221, 29196547, 58263562, 56233305,
52547525, 55812835, 87253244, 52484232, 80837360, 94098464, 52028151,
53267501, 66381929, 84381316, 59788467, 9683688, 67082008, 71605255,
80654064, 21434307, 45286643, 76556656, 82465821, 57367208, 79218980,
48460468, 59170479, 46046391, 43043164, 96544490, 83340521, 70837892,
18926791, 40818286, 28936302, 11489524, 51031183, 73860337, 13241219,
9025448, 10718828, 76360986, 26031606, 76558053, 97726139, 46473415,
48406387, 23625539, 86756012, 35164187, 49161302, 78082834, 35072237,
8602486, 29815841, 56562216, 77684187, 81751704, 20160464, 50407962,
27786415, 19893526, 934129, 37759498, 52636463, 25666982, 43262852,
38393436, 2581136, 29323250, 56950657, 5898131, 95286262, 75574581,
54057961, 6703896, 90758589, 57782642, 34492535, 41919697, 6395464,
10993500, 81212949, 34017532, 69569396, 99009936, 57129610, 67401593,
71044018, 62076698, 29533873, 71936325, 86874388, 26545032, 35695544,
30433724, 53127345, 72887083, 25390873, 63711546, 6923746, 27783723,
33199575, 35929698, 16491251, 18276792, 62744775, 92096155, 06336570,
56141974, 73007273, 31416832, 00171057, 64176982, 46938647, 58460388,
69972026, 73724304, 27435484, 51568616, 15531822, 47788699, 11818851,
41594694, 83561325, 43107163, 56965375, 10557343, 26118061, 74650126,
90076467, 10657376, 49901436, 03425162, 61164599, 15797769, 5427896,
14444084, 36795868, 18079449, 59653393, 72942548, 06763077, 33895610,
94892653, 12085268, 65174140, 79567366, 23020126, 74290047, 13498869,
21696323, 27724594, 54941003, 38229841, 7050068,
};
//C组
int[] C = {
13404901, 39952424, 47847739, 94939581, 13809950, 70966043, 11161555,
17102313, 47079425, 50682833, 74154313, 61562613, 93200452, 37103342,
18479435, 32502597, 36198035, 54210010, 73191775, 48358178, 85544503,
5996766, 54651623, 52113220, 27465181, 23871783, 22496415, 54107041,
65899605, 56528700, 82671109, 61176034, 42374678, 51612628, 63329997,
56591652, 04552733, 12789324, 89586343, 51935014, 38611966, 43916409,
70996050, 98263070, 1418023, 65345049, 21734275, 76846198, 71506230,
833171, 67128139, 41367555, 64769510, 44010700, 16475199, 93164325,
9386162, 95324041, 80688223, 67629139, 79552617, 76219736, 50368644,
45096021, 54972488, 63779011, 28862942, 73145521, 74078605, 66924991,
12806850, 02171001, 70896866, 73434467, 8487641, 44415025, 32500082,
84412833, 83896188, 52243759, 49191410, 38744339, 48079796, 44937032,
06267501, 81866886, 38575984, 25978688, 78974338, 41247821, 12356966,
64842303, 79127158, 2366944, 68000570, 12426275, 96409230, 705972,
8266503, 83820884, 8831807, 43273308, 23216105, 29196547, 95160161,
05553537, 52182214, 32641346, 91553427, 24436506, 77433749, 1979664,
52028151, 88985343, 1761499, 76203088, 63237368, 23405334, 59788467,
9683688, 67755443, 29946533, 12053603, 437479, 15200030, 45286643,
93537527, 82465821, 57367208, 53899751, 15354933, 97760830, 68933762,
80220545, 1892750, 39868288, 21524323, 69716610, 65083815, 78048499,
3227391, 83340521, 87365045, 71720254, 51031183, 89168555, 8503028,
37086236, 25103057, 87002524, 22808816, 80928090, 90741678, 15993372,
99117082, 49938176, 21755083, 86903426, 87830263, 53959980, 75758119,
59781354, 58679691, 25666982, 56307643, 47180521, 62776522, 78136608,
44882734, 90758589, 8075999, 66303819, 23480347, 11580163, 87080118,
18329165, 92514163, 89404632, 92377859, 3912329, 17499963, 59699979,
79876366, 63894807, 37857001, 86003935, 90087123, 29433345, 80298948,
61531153, 61046319, 37839841, 19421134, 48747364, 35196916, 62484573,
59907079, 36845702, 21631642, 72739317, 26283700, 80114017, 76639390,
29154110, 35159758, 47788699, 11818851, 56520669, 36396767, 36031167,
83817428, 10657376, 90076467, 14676452, 11024560, 16327605, 76048344,
14444084, 95452011, 99612346, 65172562, 84813675, 88618282, 38704390,
27998014, 63859011, 33787505, 60024611, 16229880, 13899299, 35240335,
29173227, 45036451, 66177893, 82658333, 43100730, 44520187, 74290047,
85013538, 9926730, 27724594, 95148523, 20503000, 64390907, 26006953,
98116293, 97457666, 29017396, 04634371, 70791589,
};
//记录人数
int sum = 0;
for (int i = 0; i < A.length; i++) {
for (int j = 0; j < B.length; j++) {
if(A[i] == B[j]) {
flag = 1;
for (int k = 0; k < C.length; k++) {
if(B[j] == C[k]) {
flag = 0;
}
}
if(flag == 1) {
sum++;
}
}
}
}
System.out.println(sum);
}
}
C.纸牌三角形
问题描述:
A,2,3,4,5,6,7,8,9 共9张纸牌排成一个正三角形(A按1计算)。要求每个边的和相等。
下图就是一种排法:
A
9 6
4 8
3 7 5 2
这样的排法可能会有很多。
如果考虑旋转、镜像后相同的算同一种,一共有多少种不同的排法呢?
请你计算并提交该数字。
注意:需要提交的是一个整数,不要提交任何多余内容。
思路:
1.这里正三角要求每个边的和相等,这就相当与给了一个判断条件;
2.可以用一个数组来判断是否三条边的和是否相等;
3.用全排列求出1~9的全排列,每种结果存在数组中,再写一个判断
条件看是否满足条件1,满足条件就加1;
4.最后的结果是包含重复的,题目说了旋转、镜像后相同的算同一种,
一个顶点可以在三角形的三个顶点中的任何一个,因此旋转去重结果
要除以3,镜像就是左右换除以2;
代码如下(示例):
public class Eight3_纸牌三角形 {
static int sum;
public static void main(String[] args) {
int[] arr = new int[10];
int[] help = new int[10];
dfs(1, arr, help);
System.out.println(sum / 6);
//结果为144
}
public static void dfs(int level, int[] arr, int[] help) {
//当level大于9时,就代表已经取完了数据,可以进行判断了
if(level > 9) {
//判断是否是等边三角形
int p1 = arr[1] + arr[2] + arr[3] + arr[4];
int p2 = arr[4] + arr[5] + arr[6] + arr[7];
int p3 = arr[7] + arr[8] + arr[9] + arr[1];
//如果成立,就记录个数
if(p1 == p2 && p2 == p3) {
sum++;
}
return;
}
//全排列,取出所有的排列组合
for (int i = 1; i <= 9; i++) {
if(help[i] == 0) {
help[i] = 1;
arr[level] = i;
dfs(level + 1, arr, help);
//恢复
help[i] = 0;
}
}
}
}
D.承压计算
问题描述:
X星球的高科技实验室中整齐地堆放着某批珍贵金属原料。
每块金属原料的外形、尺寸完全一致,但重量不同。
金属材料被严格地堆放成金字塔形。
7
5 8
7 8 8
9 2 7 2
8 1 4 9 1
8 1 8 8 4 1
7 9 6 1 4 5 4
5 6 5 5 6 9 5 6
5 5 4 7 9 3 5 5 1
7 5 7 9 7 4 7 3 3 1
4 6 4 5 5 8 8 3 2 4 3
1 1 3 3 1 6 6 5 5 4 4 2
9 9 9 2 1 9 1 9 2 9 5 7 9
4 3 3 7 7 9 3 6 1 3 8 8 3 7
3 6 8 1 5 3 9 5 8 3 8 1 8 3 3
8 3 2 3 3 5 5 8 5 4 2 8 6 7 6 9
8 1 8 1 8 4 6 2 2 1 7 9 4 2 3 3 4
2 8 4 2 2 9 9 2 8 3 4 9 6 3 9 4 6 9
7 9 7 4 9 7 6 6 2 8 9 4 1 8 1 7 2 1 6
9 2 8 6 4 2 7 9 5 4 1 2 5 1 7 3 9 8 3 3
5 2 1 6 7 9 3 2 8 9 5 5 6 6 6 2 1 8 7 9 9
6 7 1 8 8 7 5 3 6 5 4 7 3 4 6 7 8 1 3 2 7 4
2 2 6 3 5 3 4 9 2 4 5 7 6 6 3 2 7 2 4 8 5 5 4
7 4 4 5 8 3 3 8 1 8 6 3 2 1 6 2 6 4 6 3 8 2 9 6
1 2 4 1 3 3 5 3 4 9 6 3 8 6 5 9 1 5 3 2 6 8 8 5 3
2 2 7 9 3 3 2 8 6 9 8 4 4 9 5 8 2 6 3 4 8 4 9 3 8 8
7 7 7 9 7 5 2 7 9 2 5 1 9 2 6 5 3 9 3 5 7 3 5 4 2 8 9
7 7 6 6 8 7 5 5 8 2 4 7 7 4 7 2 6 9 2 1 8 2 9 8 5 7 3 6
5 9 4 5 5 7 5 5 6 3 5 3 9 5 8 9 5 4 1 2 6 1 4 3 5 3 2 4 1
X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X
其中的数字代表金属块的重量(计量单位较大)。
最下一层的X代表30台极高精度的电子秤。
假设每块原料的重量都十分精确地平均落在下方的两个金属块上,
最后,所有的金属块的重量都严格精确地平分落在最底层的电子秤上。
电子秤的计量单位很小,所以显示的数字很大。
工作人员发现,其中读数最小的电子秤的示数为:2086458231
请你推算出:读数最大的电子秤的示数为多少?
注意:需要提交的是一个整数,不要填写任何多余的内容。
这道题我也是思考了好久,而且是借助他人的理解才做出了的。
代码如下(示例):
import java.math.BigDecimal;
public class Eight4_承压计算 {
static double num[][] = new double[][]{
{7},
{5,8},
{7,8,8},
{9,2,7,2},
{8,1,4,9,1},
{8,1,8,8,4,1},
{7,9,6,1,4,5,4},
{5,6,5,5,6,9,5,6},
{5,5,4,7,9,3,5,5,1},
{7,5,7,9,7,4,7,3,3,1},
{4,6,4,5,5,8,8,3,2,4,3},
{1,1,3,3,1,6,6,5,5,4,4,2},
{9,9,9,2,1,9,1,9,2,9,5,7,9},
{4,3,3,7,7,9,3,6,1,3,8,8,3,7},
{3,6,8,1,5,3,9,5,8,3,8,1,8,3,3},
{8,3,2,3,3,5,5,8,5,4,2,8,6,7,6,9},
{8,1,8,1,8,4,6,2,2,1,7,9,4,2,3,3,4},
{2,8,4,2,2,9,9,2,8,3,4,9,6,3,9,4,6,9},
{7,9,7,4,9,7,6,6,2,8,9,4,1,8,1,7,2,1,6},
{9,2,8,6,4,2,7,9,5,4,1,2,5,1,7,3,9,8,3,3},
{5,2,1,6,7,9,3,2,8,9,5,5,6,6,6,2,1,8,7,9,9},
{6,7,1,8,8,7,5,3,6,5,4,7,3,4,6,7,8,1,3,2,7,4},
{2,2,6,3,5,3,4,9,2,4,5,7,6,6,3,2,7,2,4,8,5,5,4},
{7,4,4,5,8,3,3,8,1,8,6,3,2,1,6,2,6,4,6,3,8,2,9,6},
{1,2,4,1,3,3,5,3,4,9,6,3,8,6,5,9,1,5,3,2,6,8,8,5,3},
{2,2,7,9,3,3,2,8,6,9,8,4,4,9,5,8,2,6,3,4,8,4,9,3,8,8},
{7,7,7,9,7,5,2,7,9,2,5,1,9,2,6,5,3,9,3,5,7,3,5,4,2,8,9},
{7,7,6,6,8,7,5,5,8,2,4,7,7,4,7,2,6,9,2,1,8,2,9,8,5,7,3,6},
{5,9,4,5,5,7,5,5,6,3,5,3,9,5,8,9,5,4,1,2,6,1,4,3,5,3,2,4,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
};
/*
* 结题思路,先明确题意中说的“假设每块原料的重量都十分精确地平均落在下方的两个金属块上”意味着类似于某个位置处的质量应当包含其两肩上的两块金属的一半质量,
* 因此可得出,在数组中某一位置a[i][j]处的质量除了自身质量外还应包括a[i-1][j-1]和a[i-1][j]质量的一半,即a[i][j]+=a[i-1][j-1]/2+a[i-1][j]/2;
* 但应注意第一列中的数据没有“左肩”,因此要单独处理,在最后一行中所计算的最小的值,与题目中所给的最小质量作比,利用比例可得出最大质量max对应的示数
*/
public static void main(String[] args) {
double temp = 0;
//这一步的操作是为了实现这句话:假设每块原料的重量都十分精确地平均落在下方的两个金属块上
//也就是说,除了第一行的那个物体,其他物体的质量除了本身的,还要加上在它上面的那个物体的一半的质量
for (int i = 1; i < num.length; i++) {
for (int j = 0; j < num[i].length - 1; j++) {
temp = num[i - 1][j] / 2;
num[i][j] += temp;
num[i][j + 1] += temp;
}
}
double min = Integer.MAX_VALUE;
//Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。
//简单的理解:BigDecimal类是使用在小数上的,而BigInteger类是使用在整数上的(可能有不足)
BigDecimal max = BigDecimal.valueOf(Integer.MIN_VALUE); //return new BigDecimal(Double.toString(val)); 源码先转成字符串,不会丢失精度
for (int i = 0; i < num[num.length - 1].length; i++) { //最后一行上找出最大质量和最小质量
if(max.compareTo(BigDecimal.valueOf(num[num.length - 1][i])) < 0) { //按字典顺序比较两个字符串
max = BigDecimal.valueOf(num[num.length - 1][i]);
}
else if(max.compareTo(BigDecimal.valueOf(num[num.length - 1][i])) > 0) {
min = num[num.length - 1][i];
}
}
//由题意得出等式:max/最大质量的当前示数p1 == min/最小质量的当前示数p2
//我们要求的是p1 等式转化为:p1 = (max * p2) / min
double yu = (2086458231 * 1.0) / min;
System.out.println(max.multiply(BigDecimal.valueOf(yu)));
/*
* java.math.BigInteger.multiply(BigInteger val)用于计算两个BigInteger的乘法。
* 由于BigInteger类内部使用整数数组进行处理,因此对BigInteger对象的操作不如对基元进行的操作快。
* 用法:
* public BigInteger multiply(BigInteger val)
* 参数:此方法接受参数val,该参数是要与该BigInteger相乘的值。
* 返回值:此方法返回一个保存乘法(此* val)的BigInteger。
*/
//结果为72665192663.99999779405824
//四舍五入后为72665192664
}
}
E.杨辉三角
问题描述:
杨辉三角也叫帕斯卡三角,在很多数量关系中可以看到,十分重要。
第0行: 1
第1行: 1 1
第2行: 1 2 1
第3行: 1 3 3 1
第4行: 1 4 6 4 1
…
两边的元素都是1, 中间的元素是左上角的元素与右上角的元素和。
我们约定,行号,列号都从0计数。
所以: 第6行的第2个元素是15,第3个元素是20
直观地看,需要开辟一个二维数组,其实一维数组也可以胜任。
如下程序就是用一维数组“腾挪”的解法。
public class A{
// 杨辉三角形的第row行第col列
static long f(int row, int col){
if(row<2) return 1;
if(col==0) return 1;
if(col==row) return 1;
long[] a = new long[row+1];
a[0]=1;
a[1]=1;
int p = 2;
while(p<=row){
a[p] = 1;
for( __________________ ) a[q] = a[q] + a[q-1];
p++;
}
return a[col];
}
public static void main(String[] args){
System.out.println(f(6,2));
System.out.println(f(6,3));
}
}
请仔细分析源码,并完成划线部分缺少的代码。
注意:只提交缺少的代码,不要提交已有的代码和符号。也不要提交说明性文字。
答案是:int q = p - 1; q >= 1; q–
F.最大公共子串
问题描述:
最大公共子串长度问题就是:
求两个串的所有子串中能够匹配上的最大长度是多少。
比如:“abcdkkk” 和 “baabcdadabc”,
可以找到的最长的公共子串是"abcd",所以最大公共子串长度为4。
下面的程序是采用矩阵法进行求解的,这对串的规模不大的情况还是比较有效的解法。
请分析该解法的思路,并补全划线部分缺失的代码。
public class Main{
static int f(String s1, String s2){
char[] c1 = s1.toCharArray();
char[] c2 = s2.toCharArray();
int[][] a = new int[c1.length+1][c2.length+1];
int max = 0;
for(int i=1; i<a.length; i++){
for(int j=1; j<a[i].length; j++){
if(c1[i-1]==c2[j-1]) {
a[i][j] = __________________; //填空
if(a[i][j] > max) max = a[i][j];
}
}
}
return max;
}
public static void main(String[] args){
int n = f("abcdkkk", "baabcdadabc");
System.out.println(n);
}
}
注意:只提交缺少的代码,不要提交已有的代码和符号。也不要提交说明性文字。
答案:a[i - 1][j - 1] + 1
G.Excel地址
问题描述:
Excel单元格的地址表示很有趣,它使用字母来表示列号。
比如,
A表示第1列,
B表示第2列,
Z表示第26列,
AA表示第27列,
AB表示第28列,
BA表示第53列,
…
当然Excel的最大列号是有限度的,所以转换起来不难。
如果我们想把这种表示法一般化,可以把很大的数字转换为很长的字母序列呢?
本题目既是要求对输入的数字, 输出其对应的Excel地址表示方式。
例如,
输入:
26
则程序应该输出:
Z
再例如,
输入:
2054
则程序应该输出:
BZZ
我们约定,输入的整数范围[1,2147483647]
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
代码如下(示例):
import java.util.Scanner;
public class Eight7_Excel地址 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
scanner.close();
//创建一个数组用来存储由数字转成字母的数据
char[] result = new char[1000];
//从0开始
int i = 0;
//当n为0时,退出循环
while(n > 0) {
int k = n % 26;
//如果为0,说明为Z
if(k == 0) {
result[i++] = 'Z';
n -= 26;
}else {
//如果不为0,则就是当前取余得到的数相对应的字母
char ch = (char)('A' - 1 + k);
result[i++] = ch;
n -= k;
}
n /= 26;
}
//输出
for (int j = i - 1; j >= 0; j--) {
System.out.print(result[j]);
}
}
}
H.拉马车
问题描述:
小的时候,你玩过纸牌游戏吗? 有一种叫做“拉马车”的游戏,规则很简单,却很吸引小朋友。
其规则简述如下:
假设参加游戏的小朋友是A和B,游戏开始的时候,他们得到的随机的纸牌序列如下:
A方:[K, 8, X, K, A, 2, A, 9, 5, A]
B方:[2, 7, K, 5, J, 5, Q, 6, K, 4]
其中的X表示“10”,我们忽略了纸牌的花色。
从A方开始,A、B双方轮流出牌。
当轮到某一方出牌时,他从自己的纸牌队列的头部拿走一张,放到桌上,并且压在最上面一张纸牌上(如果有的话)。
此例中,游戏过程:
A出K,B出2,A出8,B出7,A出X,此时桌上的序列为:
K,2,8,7,X
当轮到B出牌时,他的牌K与桌上的纸牌序列中的K相同,则把包括K在内的以及两个K之间的纸牌都赢回来,放入自己牌的队尾。注意:为了操作方便,放入牌的顺序是与桌上的顺序相反的。
此时,A、B双方的手里牌为:
A方:[K, A, 2, A, 9, 5, A]
B方:[5, J, 5, Q, 6, K, 4, K, X, 7, 8, 2, K]
赢牌的一方继续出牌。也就是B接着出5,A出K,B出J,A出A,B出5,又赢牌了。
5,K,J,A,5
此时双方手里牌:
A方:[2, A, 9, 5, A]
B方:[Q, 6, K, 4, K, X, 7, 8, 2, K, 5, A, J, K, 5]
注意:更多的时候赢牌的一方并不能把桌上的牌都赢走,而是拿走相同牌点及其中间的部分。但无论如何,都是赢牌的一方继续出牌,有的时候刚一出牌又赢了,也是允许的。
当某一方出掉手里最后一张牌,但无法从桌面上赢取牌时,游戏立即结束。
对于本例的初始手牌情况下,最后A会输掉,而B最后的手里牌为:
9K2A62KAX58K57KJ5
本题的任务就是已知双方初始牌序,计算游戏结束时,赢的一方手里的牌序。当游戏无法结束时,输出-1。
输入为2行,2个串,分别表示A、B双方初始手里的牌序列。
输出为1行,1个串,表示A先出牌,最后赢的一方手里的牌序。
例如,
输入:
96J5A898QA
6278A7Q973
则程序应该输出:
2J9A7QA6Q6889977
再比如,
输入:
25663K6X
7448
J88A5KJXX45A
则程序应该输出:
6KAJ458KXAX885XJ645
我们约定,输入的串的长度不超过30
笨笨有话说:
不断删除前边的,又要后边添加… 如果用数组,需要开一个大点的,请佛祖保佑在游戏结束前,不会用到数组的边缘。
歪歪有话说:
反正串也不长,不如每次操作都返回一个新的串。
默默有话说:
我一般都不吱声,这是典型的队列结构,动态数组最好,没有?自己造一个呗!
这道题说难也不难,只要按照题目要求一步步来即可。
代码如下(示例):
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Eight8_拉马车 {
//创建一个List集合用来表示桌子
static List<Character> list = new ArrayList<Character>();
//创建一个布尔数组,用来判断是否出现过
static boolean[] check = new boolean[128];
static StringBuilder sA;//表示A
static StringBuilder sB;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String A = scanner.nextLine();
String B = scanner.nextLine();
scanner.close();
sA = new StringBuilder(A);
sB = new StringBuilder(B);
while(true) {
boolean booA = A();
while(booA) {
booA = A();
}
if(sA.length() == 0) {
System.out.println(sB);
break;
}
boolean booB = B();
while(booB) {
booB = B();
}
if(sB.length() == 0) {
System.out.println(sA);
break;
}
}
}
//A出牌
public static boolean A() {
//打出一张牌
char cA = sA.charAt(0);
list.add(cA);
//删除打出的那张牌
sA.deleteCharAt(0);
//如果桌子上已经有这张牌了,那么当A打出这张牌时,就可以收牌了
if(check[cA]) {
int k = list.size() - 1;
sA.append(list.get(k));
check[list.get(k)] = false;
//既然这张牌已经加到A中,那么就要将它移除出去
list.remove(k--);
//这是要判断在两张相同的牌中是否还有牌
while(list.get(k) != cA) {
sA.append(list.get(k));
check[list.get(k)] = false;
list.remove(k--);
}
//当加完中间部分的或者没有中间部分的,就将与第一张相同的牌加进去
sA.append(list.get(k));
check[list.get(k)] = false;
list.remove(k--);
return true;//赢了,继续出牌
}
check[cA] = true;
return false;
}
//B出牌
public static boolean B() {
//打出一张牌
char cB = sB.charAt(0);
list.add(cB);
//删除打出的那张牌
sB.deleteCharAt(0);
//如果桌子上已经有这张牌了,那么当A打出这张牌时,就可以收牌了
if(check[cB]) {
int k = list.size() - 1;
sB.append(list.get(k));
check[list.get(k)] = false;
//既然这张牌已经加到A中,那么就要将它移除出去
list.remove(k--);
//这是要判断在两张相同的牌中是否还有牌
while(list.get(k) != cB) {
sB.append(list.get(k));
check[list.get(k)] = false;
list.remove(k--);
}
//当加完中间部分的或者没有中间部分的,就将与第一张相同的牌加进去
sB.append(list.get(k));
check[list.get(k)] = false;
list.remove(k--);
return true;//赢了,继续出牌
}
check[cB] = true;
return false;
}
}
I.青蛙跳杯子
问题描述:
X星球的流行宠物是青蛙,一般有两种颜色:白色和黑色。
X星球的居民喜欢把它们放在一排茶杯里,这样可以观察它们跳来跳去。
如下图,有一排杯子,左边的一个是空着的,右边的杯子,每个里边有一只青蛙。
*WWWBBB
其中,W字母表示白色青蛙,B表示黑色青蛙,*表示空杯子。
X星的青蛙很有些癖好,它们只做3个动作之一:
- 跳到相邻的空杯子里。
- 隔着1只其它的青蛙(随便什么颜色)跳到空杯子里。
- 隔着2只其它的青蛙(随便什么颜色)跳到空杯子里。
对于上图的局面,只要1步,就可跳成下图局面:
WWW*BBB
本题的任务就是已知初始局面,询问至少需要几步,才能跳成另一个目标局面。
输入为2行,2个串,表示初始局面和目标局面。
输出要求为一个整数,表示至少需要多少步的青蛙跳。
例如:
输入:
WWBB
WWBB
则程序应该输出:
2
再例如,
输入:
WWWBBB
BBBWWW
则程序应该输出:
10
我们约定,输入的串的长度不超过15
在这道题上是花了很多时间,还借助了他人的帮助,才写出来。
代码如下(示例):
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.TreeSet;
public class Eight9_青蛙跳杯子 {
static String begin;//初始局面
static String end;//目标局面
static int cur;//保存星号的位置
static String temp;//保存临时局面
static int count;//树的深度表示搜索的次数
static int num_1 = 1;//当前这一代节点的个数
static int num_2 = 0;//保存下一代子节点的个数
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
begin = scanner.nextLine();
end = scanner.nextLine();
bfs();
System.out.println(count + 1);
}
//首先确认星号的位置,也就是空杯子的位置
public static int findstar(String begin) {
for (int i = 0; i < begin.length(); i++) {
if(begin.charAt(i) == '*') {
return i;
}
}
//如果没有找到,就返回-1
return -1;
}
//交换两个字符的位置,也就是青蛙跳杯子
public static String exchange(String begin, int m, int n) {
//字符串转成字符数组
char[] start = begin.toCharArray();
String result = "";//用来进行拼接的
//以下这里就是进行跳跃了
char temp = start[m];
start[m] = start[n];
start[n] = temp;
//而跳跃的实质就是两者进行交换
for (int i = 0; i < start.length; i++) {
result += start[i];
}
return result;
}
//BFS
public static void bfs() {
//队列保存每一代子节点,也就是每次青蛙跳了一次后的局面
Queue<String> queue = new LinkedList<String>();
/*
* 很好,又有一个新知识点。
* Queue: 基本上,一个队列就是一个先入先出(FIFO)的数据结构(符合广搜)
* Queue接口与List、Set同一级别,都是继承了Collection接口。LinkedList实现了Deque接口。
*/
//剪枝,防止青蛙来回跳相同的局面
TreeSet<String> treeSet = new TreeSet<String>();
/*
* 对这个TreeSet还是不熟悉
* Java中的TreeSet是Set的一个子类,TreeSet集合是用来对象元素进行排序的,同样他也可以保证元素的唯一。
* 实现了Set接口的子接口SortedSet,基本特征和HashSet类一样,
* 只是增加了排序功能。
*/
while(true) {
if(queue.isEmpty()) {//判断字符串是否为空
queue.add(begin);
treeSet.add(begin);
}
if(num_1 == 0) {
//每一代的节点为0时,num1重新赋值为num2,num2重置
num_1 = num_2;
num_2 = 0;
count++;
}
String str = queue.poll();//poll()方法:移除并返问队列头部的元素。如果队列为空,则返回null
cur = findstar(str);
if(cur - 1 >= 0) {
temp = exchange(str, cur, cur - 1);
if(temp.equals(end)) { //找到了直接退出即可
break;
}
if(!treeSet.contains(temp)) {
queue.add(temp);
treeSet.add(temp);
num_2++;
}
}
if(cur - 2 >= 0) {
temp = exchange(str, cur, cur - 2);
if(temp.equals(end)) {
break;
}
if(!treeSet.contains(temp)) {
queue.add(temp);
treeSet.add(temp);
num_2++;
}
}
if(cur - 3 >= 0) {
temp = exchange(str, cur, cur - 3);
if(temp.equals(end)) {
break;
}
if(!treeSet.contains(temp)) {
queue.add(temp);
treeSet.add(temp);
num_2++;
}
}
if(cur + 1 < begin.length()) {
temp = exchange(str, cur, cur + 1);
if(temp.equals(end)) {
break;
}
if(!treeSet.contains(temp)) {
queue.add(temp);
treeSet.add(temp);
num_2++;
}
}
if(cur + 2 < begin.length()) {
temp = exchange(str, cur, cur + 2);
if(temp.equals(end)) {
break;
}
if(!treeSet.contains(temp)) {
queue.add(temp);
treeSet.add(temp);
num_2++;
}
}
if(cur + 3 < begin.length()) {
temp = exchange(str, cur, cur + 3);
if(temp.equals(end)) {
break;
}
if(!treeSet.contains(temp)) {
queue.add(temp);
treeSet.add(temp);
num_2++;
}
}
num_1--;
}
}
}
J.图形排版
问题描述:
小明需要在一篇文档中加入 N 张图片,其中第 i 张图片的宽度是 Wi,高度是 Hi。
假设纸张的宽度是 M,小明使用的文档编辑工具会用以下方式对图片进行自动排版:
该工具会按照图片顺序,在宽度 M 以内,将尽可能多的图片排在一行。该行的高度是行内最高的图片的高度。例如在 M=10 的纸张上依次打印 3x4, 2x2, 3x3 三张图片,则效果如下图所示,这一行高度为4。(分割线以上为列标尺,分割线以下为排版区域;数字组成的矩形为第x张图片占用的版面)
0123456789
111
111 333
11122333
11122333
如果当前行剩余宽度大于0,并且小于下一张图片,则下一张图片会按比例缩放到宽度为当前行剩余宽度(高度向上取整),然后放入当前行。例如再放入一张4x9的图片,由于剩余宽度是2,这张图片会被压缩到2x5,再被放入第一行的末尾。此时该行高度为5:
0123456789
44
111 44
111 33344
1112233344
1112233344
如果当前行剩余宽度为0,该工具会从下一行开始继续对剩余的图片进行排版,直到所有图片都处理完毕。此时所有行的总高度和就是这 N 张图片的排版高度。例如再放入11x1, 5x5, 3x4 的图片后,效果如下图所示,总高度为11:
0123456789
44
111 44
111 33344
1112233344
1112233344
5555555555
66666
66666777
66666777
66666777
66666777
现在由于排版高度过高,图片的先后顺序也不能改变,小明只好从 N 张图片中选择一张删除掉以降低总高度。他希望剩余N-1张图片按原顺序的排版高度最低,你能求出最低高度是多少么?
输入:
第一行包含两个整数 M 和 N,分别表示纸张宽度和图片的数量。
接下来 N 行,每行2个整数Wi, Hi,表示第 i 个图大小为 Wi*Hi。
对于30%的数据,满足1<=N<=1000
对于100%的数据,满足1<=N<=100000,1<=M, Wi, Hi<=100
输出:
一个整数,表示在删除掉某一张图片之后,排版高度最少能是多少。
样例输入:
4 3
2 2
2 3
2 2
样例输出:
2
另一个示例,
样例输入:
2 10
4 4
4 3
1 3
4 5
2 1
2 3
5 4
5 3
1 5
2 4
样例输出:
17
很抱歉,这道题没想出来。如果有大佬,希望能帮帮我!