目录
- 前言
- 第一题-排序字母
- 第二题-特殊时间
- 第三题-纸张尺寸
- 第四题-求和
- 第五题-矩形拼接
- 第六题-选数异或
- 第七题-GCD
- 第八题-青蛙过河
- 第九题-因数平方和
- 第十题-最长不下降子序列
前言
前些日子也是刚经过考试, 没怎么学过算法, 感觉还有待提高, 此文章是本人对于第十三届蓝桥杯Java-C组考题的解析以及理解, 不一定都对, 有更好提议的同学可以在评论里留出; 那么话不多说 上正菜.
第一题-排序字母
那么,首先看到这道题的时候应该想到与之关联的思路应该是什么, 可以通过将字符串内要排序的字母来放入一个数组进行排序处理, 这块推荐使用Array
的sort
方法, 其实看名字也可以看出这是一整个写好的排序方法;
package example;
import java.util.Arrays;
/**
* @author OGtwelve
* @Description 第十三届蓝桥杯Java-C组第一题 (排序字母)
*/
public class HelloWorld {
public static void main(String[] argv){
String needToBeSortedString = "WHERETHEREISAWILLTHEREISAWAY";
//一句谚语: Where there is a will there is a way (有志者事竟成)
char[] sortIntoChars = needToBeSortedString.toCharArray();
//char类型数组, 由于String类型提供了 .toCharArray()这个方法, 所以可以直接用数组获取
Arrays.sort(sortIntoChars);
//这块是直接用Arrays数组处理工具直接.sort()方法进行排序
for (int i = 0; i < sortIntoChars.length; i++) {
//这块循环条件直接使用获取到的char类型数组长度即可
System.out.print(sortIntoChars[i]);
//输出结果是 AAAEEEEEEHHHIIILLRRRSSTTWWWY
}
}
}
可能有些同学还对这块直接使用的sort
方法不是很了解, 下面则为sort的官方解释以及本人理解;
static void sort(char[] a)
对指定的 任意类型数组按数字升序进行排序
在这里我直接用了char[]数组来代替
默认为升序排列
//--------------------------------------------------------
static void sort(char[] a, int begin, int end)
对指定数组的指定范围按数字升序进行排序。
char[]可以指定为int,float,double,long,byte等
begin- 排序的第一个元素的下标/索引(包括)
end- 排序的最后一个元素的下标/索引(不包括)
第二题-特殊时间
过于简单 不多做赘述 答案为212;
第三题-纸张尺寸
因为这道题是对折, 所以每两次折完后, 原本的长就是宽了, 例如 A0
是长1189
宽841,
按题目对折A1为将长度对半拆分宽度不变, 所以这之后折叠完后的大小就变成了(1189/2=)594
和841
, 以此类推;
当然这道题可以按最暴力的实现方法, 直接用switch
语句对输入的纸张大小进行判断然后输出对应计算出的大小,输出写个判断, 如果这两个数字中间哪个较大,那么哪个就在输出中排第一位, 较小则否;
不过一般来说, 能写算法还是尽量写成算法, 话不多说 上代码;
package example;
import java.util.Scanner;
/**
* @author OGtwelve
* @Description 第十三届蓝桥杯Java-C组第三题 (纸张尺寸)
*/
public class HelloWorld {
public static void main(String[] argv){
Scanner input = new Scanner(System.in);
int paperLength = 1189;//长度
int paperWeight = 841;//宽度
int tempNum = 0; //临时存储被修改的宽度
int numberWithoutA = Integer.parseInt(input.next().replace("A","").replace("a",""));
//将输入的纸张大小 A 去除进行再次判断
input.close();
if (numberWithoutA<=9){
if (numberWithoutA!=0){ //不能等于0是因为长宽的默认值就是A0大小的属性
for (int i = 1; i <=9; i++){
tempNum = paperWeight; //先将宽度存入临时数字内
paperWeight = paperLength/2; //再将折叠后(即为除以2)的长度赋值给宽度
paperLength = tempNum; //最后将折叠前的宽度返还给长度
if (i==numberWithoutA){ //这样判断是为了能让循环在输入的纸张大小号处跳出
break;
}
}
}
System.out.println(paperLength + "\n" + paperWeight);
}else{
System.out.println("请输入A0-A9");
}
}
}
第四题-求和
这是一道比较典型的递推类型的题目;
直接通过看输入以及输出样式, 输入第一行为输入第二行的个数, 输入的第二行则是四个单独的数字;
结果的流程在本题内为1*3 + 1*6 + 1*9 + 3*6 + 3*9 + 6*9 = 117
或者1*(3+6+9) + 3*(6+9) + 6*(9) = 117
那么这样列出来的话, 就很容易的找到规律.
那么具体的流程是这样, 话不多说 上代码.
package example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
/**
* @author OGtwelve
* @Description 第十三届蓝桥杯Java-C组第四题 (求和)
*/
public class HelloWorld {
public static void main(String[] argv) throws IOException {
int num = streamTokenizer(), sum = 0, l1, l2=0;
while (num-- > 0){
l1 = streamTokenizer();
l2 += l1 * sum;
sum += l1;
}
System.out.println(l2);
}
public static int streamTokenizer() throws IOException {
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
//这块输入可以用Scanner写 不过时间可能会超时
//BufferedReader在相同时间内是以一整块内存去读取内容的 要比一个一个读取快的多
in.nextToken();
return (int)in.nval;
}
}
第五题-矩形拼接
尝试理解代码, 一律的CV是没用的;
import java.util.*;
/**
* @author OGtwelve
* @Description 第十三届蓝桥杯Java-C组第五题 (矩形拼接)
*/
public class HelloWorld {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
// number of sets of squares
int n = scan.nextInt();
// minimum number of glued sides for each set
int[] b = new int[n];
for (int i = 0; i < n; i++) {
// read in the three squares
int[][] squares = new int[3][2];
for (int j = 0; j < 3; j++) {
squares[j][0] = scan.nextInt();
squares[j][1] = scan.nextInt();
}
// check if any of the squares have matching sides
boolean matchingSides = false;
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 3; k++) {
if (j != k && (squares[j][0] == squares[k][0] || squares[j][0] == squares[k][1] || squares[j][1] == squares[k][0] || squares[j][1] == squares[k][1])) {
matchingSides = true;
break;
}
}
if (matchingSides) {
break;
}
}
// if there are matching sides, we only need 4 glued sides
// otherwise, we need all 6 sides to be glued
b[i] = matchingSides ? 4 : 6;
}
// print the results
for (int i = 0; i < n; i++) {
System.out.println(b[i]);
}
}
}
第六题-选数异或
无脑动态规划 上代码;
package example;
import java.io.*;
/**
* @author OGtwelve
* @Description 第十三届蓝桥杯Java-C组第六题 (选数异或)
*/
public class HelloWorld {
public static void main(String[] args) throws IOException {
PrintWriter out = new PrintWriter(System.out);
int n = streamTokenizer(), m = streamTokenizer(), x = streamTokenizer();
int[] map = new int[1 << 20];
int[] frat = new int[n + 1];
for (int i = 1; i <= n; ++i) {
int a = streamTokenizer();
frat[i] = Math.max(frat[i - 1], map[a ^ x]);
map[a] = i;
}
for (int i = 0; i < m; ++i) {
int set1 = streamTokenizer();
int set2 = streamTokenizer();
out.println(frat[set2] >= set1 ? "YES" : "NO");
}
out.flush();
}
public static int streamTokenizer() throws IOException {
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
in.nextToken();
return (int)in.nval;
}
}
第七题-GCD
package example;
import java.io.*;
import java.util.StringTokenizer;
/**
* @author OGtwelve
* @Description 第十三届蓝桥杯Java-C组第七题 (GCD)
*/
public class HelloWorld {
public static void main(String[] args) throws IOException {
InputReader in = new InputReader(System.in);
long a = Long.parseLong(in.next()), b = Long.parseLong(in.next());
long c = Math.abs(a - b);
if (c == 0 || c == 1) {
System.out.print("1");
}else {
System.out.print(Math.min((-a % c + c) % c, (-b % c + c) % c));
}
}
public static class InputReader {
BufferedReader reader = null;
StringTokenizer token = null;
InputReader(InputStream in) {
this.reader = new BufferedReader(new InputStreamReader(in));
}
public String next() throws IOException {
if (token == null || !token.hasMoreTokens()) {
token = new StringTokenizer(reader.readLine());
}
return token.nextToken();
}
}
}
第八题-青蛙过河
简单二分; 上代码:
import java.util.*;
/**
* @author OGtwelve
* @Description 第十三届蓝桥杯Java-C组第八题 (青蛙过河)
*/
public class HelloWorld {
private static int a, b;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
b = in.nextInt();
a = in.nextInt();
int[] z = new int[b + 10];
int[] pre = new int[b + 10];
for (int i = 1; i <= b - 1; i++) {
z[i] = in.nextInt();
pre[i] = pre[i - 1] + z[i];
}
int l = 1, r = b, ans = -1;
while (l <= r) {
int mid = (l + r) / 2;
if (judge(mid, pre)) {
ans = mid;
r = mid - 1;
} else {
l = mid + 1;
}
}
System.out.println(ans);
}
public static boolean judge(int y, int[] pre) {
for (int l = 1; l <= HelloWorld.b - y; l++) {
int r = l + y - 1;
if (pre[r] - pre[l - 1] < 2 * a) {
return false;
}
}
return true;
}
}
第九题-因数平方和
package example;
import java.io.*;
/**
* @author OGtwelve
* @Description 第十三届蓝桥杯Java-C组第九题 (因数平方和)
*/
public class HelloWorld {
public static void main(String[] args) throws IOException {
int p = 1000000007 /* 10^9+7 值*/, s = 166666668;
int n = streamTokenizer();
long tmp, sum = 0, res = 0;
for (int i = 1, j; i <= n; i = j + 1) {
j = n / (n / i);
tmp = sum;
sum = j * (j + 1L) % p * (2L * j + 1) % p * s % p;//取模没整明白 感觉还是有bug
res = (res + (n / i) * (sum - tmp) + p) % p;
}
System.out.println(res);
}
public static int streamTokenizer() throws IOException {
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
in.nextToken();
return (int)in.nval;
}
}
这道题说实话不一定对 写的时候对这块有点思绪错乱 具体思路参考了以下:
算法学习(1):一个数的幂除以质数(10^9+7)的余数
第十题-最长不下降子序列
经典动态规划 不想写 摆了 😃
import java.util.*;
/**
* @author OGtwelve
* @Description 第十三届蓝桥杯Java-C组第十题(最长不下降子序列)
*/
public class HelloWorld {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
int res = 1; // 初始化最终结果为 1
for (int i = 0; i + k < n; i++) { // 枚举修改的起点
int max = a[i]; // 修改后的值取 a[i] 到 a[i + k] 中的最大值
for (int j = i + 1; j <= i + k; j++) {
max = Math.max(max, a[j]);
}
int[] b = a.clone(); // 复制一份 a 数组,方便修改
for (int j = i; j <= i + k; j++) { // 将 a[i] 到 a[i + k] 修改为 max
b[j] = max;
}
int[] dp = new int[n]; // dp[i] 表示以 b[i] 为结尾的最长不下降子序列的长度
dp[0] = 1;
for (int j = 1; j < n; j++) {
int m = 0;
for (int l = 0; l < j; l++) {
if (b[j] >= b[l]) {
m = Math.max(m, dp[l]);
}
}
dp[j] = m + 1;
res = Math.max(res, dp[j]); // 更新最终结果
}
}
System.out.println(res);
}
}