2020年4月18日蓝桥杯省模拟赛
第一题:
问题描述:
由1对括号,可以组成一种合法括号序列:()。
由2对括号,可以组成两种合法括号序列:()()、(())。
由4对括号组成的合法括号序列一共有多少种?
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
答案:14
法一: 由于给的数字并不是特别的大,直接在纸上算也可以
法二: 参考LeetCode22题,括号生成。
算法参考图片:
package zzctst;
import java.util.ArrayList;
import java.util.Scanner;
public class test01 {
static int sum = 0;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
ArrayList<String> list = new ArrayList<String>();
int n = in.nextInt();
dfs("", n, n, list);
System.out.println(sum);
}
static void dfs(String str, int left, int right, ArrayList<String> list){
//出口
if(left == 0 && right == 0){
sum++;
list.add(str);
return;
}
//特别的,若左括号的剩余量大于右括号
if(left > right) return;
//拼接左括号
if(left > 0){
dfs(str + "(", left - 1, right, list);
}
//拼接右括号
if(right > 0){
dfs(str + ")", left, right - 1, list);
}
}
}
第二题:
在计算机存储中,12.5MB是多少字节?
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
答案:13107200
第三题:
将LANQIAO中的字母重新排列,可以得到不同的单词,如LANQIAO、AAILNOQ等,注意这7个字母都要被用上,单词不一定有具体的英文意义。
请问,总共能排列如多少个不同的单词。
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
答案:2520
注意:中间有两个A
法一:7!/2 = 2520
法二:代码如下(注意去重)LeetCode46题
package zzctst;
import java.util.Arrays;
import java.util.HashSet;
public class test03 {
static HashSet<String> set = new HashSet<String>();
public static void main(String[] args) {
String str = "LANQIAO";
char[] ch = str.toCharArray();
dfs(ch, 0);
System.out.println(set.size());
}
static void dfs(char [] arra, int begin){
if(begin == arra.length){
set.add(new String(arra));
return;
}
for(int i = begin; i < arra.length; i++){
//每个数字当一次头
char temp = arra[begin];
arra[begin] = arra[i];
arra[i] = temp;
dfs(arra, begin + 1);
//回溯
temp = arra[begin];
arra[begin] = arra[i];
arra[i] = temp;
}
}
}
第四题:(概念)
一个包含有2019个结点的无向连通图,最少包含多少条边?
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
答案:2018
第五题
给定三个整数 a, b, c,如果一个整数既不是 a 的整数倍也不是 b 的整数倍还不是 c 的整数倍,则这个数称为反倍数。
请问在 1 至 n 中有多少个反倍数。
输入格式
输入的第一行包含一个整数 n。
第二行包含三个整数 a, b, c,相邻两个数之间用一个空格分隔。
输出格式
输出一行包含一个整数,表示答案。
样例输入
30
2 3 6
样例输出
10
样例说明
以下这些数满足要求:1, 5, 7, 11, 13, 17, 19, 23, 25, 29。
package zzctst;
import java.util.Scanner;
public class test05 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int a = in.nextInt();
int b = in.nextInt();
int c = in.nextInt();
//遍历1到n
int sum = 0;
for(int i = 1; i <= n; i++){
if(i % a != 0 && i % b != 0 && i % c != 0){
sum++;
}
}
System.out.println(sum);
}
}
第六题:
给定一个单词,请使用凯撒密码将这个单词加密。
凯撒密码是一种替换加密的技术,单词中的所有字母都在字母表上向后偏移3位后被替换成密文。即a变为d,b变为e,…,w变为z,x变为a,y变为b,z变为c。
例如,lanqiao会变成odqtldr。
输入格式
输入一行,包含一个单词,单词中只包含小写英文字母。
输出格式
输出一行,表示加密后的密文。
样例输入
lanqiao
样例输出
Odqtldr
package zzctst;
import java.util.Scanner;
public class test06 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
//System.out.println((char)((int)'a'+3));
String str = in.next();
char[] ch = str.toCharArray();
for(int i = 0; i < str.length(); i++){
if(ch[i] == 'x'){
ch[i] = 'a';
}else if(ch[i] == 'y'){
ch[i] = 'b';
}else if(ch[i] == 'z'){
ch[i] = 'c';
}else{
ch[i] = (char)((int)ch[i] + 3);
}
}
System.out.println(new String(ch));
}
}
第七题
对于一个 n 行 m 列的表格,我们可以使用螺旋的方式给表格依次填上正整数,我们称填好的表格为一个螺旋矩阵。
例如,一个 4 行 5 列的螺旋矩阵如下:
1 2 3 4 5
14 15 16 17 6
13 20 19 18 7
12 11 10 9 8
输入格式
输入的第一行包含两个整数 n, m,分别表示螺旋矩阵的行数和列数。
第二行包含两个整数 r, c,表示要求的行号和列号。
输出格式
输出一个整数,表示螺旋矩阵中第 r 行第 c 列的元素的值。
样例输入
4 5
2 2
样例输出
15
我的理解:LeetCode54题
package zzc.leetCode;
import java.util.Arrays;
import java.util.Scanner;
public class test07 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int m = in.nextInt();
int n = in.nextInt();
int r = in.nextInt();
int c = in.nextInt();
int[][] arra = new int[m][n];
int[][] book = new int[m][n];
//限定活动区域
int x1 = 0, x2 = m - 1;
int y1 = 0, y2 = n - 1;
//填充数字
int k = 1;
//右下左上
while(x1 <= x2 && y1 <= y2){
//右
for (int p = y1; p <= y2; p++) {
if(book[x1][p] == 0){
arra[x1][p] = k++;
book[x1][p] = 1;
}
}
x1++;
//下
for (int p = x1; p <= x2; p++) {
if(book[p][y2] == 0){
arra[p][y2] = k++;
book[p][y2] = 1;
}
}
y2--;
//左
for(int p = y2; p >= y1; p--){
if(book[x2][p] == 0){
arra[x2][p] = k++;
book[x2][p] = 1;
}
}
x2--;
//上
for(int p = x2; p >= x1; p--){
if(book[p][y1] == 0){
arra[p][y1] = k++;
book[p][y1] = 1;
}
}
y1++;
}
// for(int i = 0; i < m; i++){
// System.out.println(Arrays.toString(arra[i]));
// }
System.out.println(arra[r - 1][c - 1]);
}
}
第八题
如果一个序列的奇数项都比前一项大,偶数项都比前一项小,则称为一个摆动序列。即 a[2i]a[2i]。
小明想知道,长度为 m,每个数都是 1 到 n 之间的正整数的摆动序列一共有多少个。
输入格式
输入一行包含两个整数 m,n。
输出格式
输出一个整数,表示答案。答案可能很大,请输出答案除以10000的余数。
样例输入
3 4
样例输出
14
样例说明
以下是符合要求的摆动序列:
2 1 2
2 1 3
2 1 4
3 1 2
3 1 3
3 1 4
3 2 3
3 2 4
4 1 2
4 1 3
4 1 4
4 2 3
4 2 4
4 3 4
法一: 在这之前需一个过渡:就是当m = 3,n = 4时,为了得到最终结果,我们可以这样做:
public static void main(String[] args) {
int m = 3, n = 4;
int sum = 0;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
for(int k = 1; k <= n; k++){
if(j < i && j < k){
// System.out.println(i+" "+j+" "+k);
sum++;
}
}
}
}
System.out.println(sum);
}
这样就能得出m = 3, n = 4时的答案,但是这里只用到了n = 4,m = 3并没有用到。细心的观察你会发现,有三个for循环。
大胆设想(超时)
要是m = 4呢。是不是应该出现四个for循环。要是m = 10呢。是不是有点深搜的味儿了。
能想到深搜基本就差不多了:这里的递归体并不难写,本人是难在了出口判断这个地方,数组越界想了我好长时间
package zzctst;
import java.util.Scanner;
public class test08 {
static int ans = 0;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int m = in.nextInt();
int n = in.nextInt();
int[] arra = new int[m];
f(arra, m , n, 0);
System.out.println(ans);
}
static void f(int[] arra, int m, int n, int step){
if(m == step){
//检查
boolean flag = true;
//数组长度为偶数
if(arra.length % 2 == 0){
for (int i = 1; i < arra.length - 1; i++) {
if(i % 2 != 0){
if(arra[i] < arra[i - 1] && arra[i] < arra[i + 1]){
continue;
}else{
flag = false;
break;
}
}
flag = flag && (arra[arra.length - 1] < arra[arra.length - 2]);
}
}else{
//奇数
for (int i = 1; i < arra.length; i+=2) {
if(arra[i] < arra[i - 1] && arra[i] < arra[i + 1]){
continue;
}else{
flag = false;
break;
}
}
}
if(flag){
// for(int a : arra){
// System.out.print(a + " ");
// }
// System.out.println();
ans++;
}
return;
}
for(int i = 1; i <= n; i++){
arra[step] = i;
f(arra, m, n, step + 1);
}
}
}
import java.util.Scanner;
public class 摆动序列 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int m = in.nextInt();
int n = in.nextInt();
//dp数组,第一列状态
int[] dp = new int[n + 2];
dp[0] = 0; dp[n] = 0;
for(int i = 1; i < dp.length - 1; i++){
dp[i] = 1;
}
System.out.println(f(dp, m, n));
}
static int f(int[] dp, int m, int n){
//总数
int sum = 0;
//155033954
for(int i = 2; i <= m ;i++){
//中间夹的较小的一列
if(i % 2 == 0){
for(int j = 1; j <= dp.length - 2; j++){
int tempSum = 0;
for(int k = j + 1; k < dp.length; k++){
tempSum += dp[k] % 10000;
}
dp[j] = tempSum;
}
}else{
for(int j = dp.length - 2; j >= 1; j--){
int tempSum = 0;
for(int k = j - 1; k >= 0; k--){
tempSum += dp[k] % 10000;
}
dp[j] = tempSum;
}
}
}
for(int k = 0; k < dp.length; k++)
sum += dp[k] % 10000;
return sum % 10000;
}
}
第九题
小明和朋友们一起去郊外植树,他们带了一些在自己实验室精心研究出的小树苗。
小明和朋友们一共有 n 个人,他们经过精心挑选,在一块空地上每个人挑选了一个适合植树的位置,总共 n 个。他们准备把自己带的树苗都植下去。
然而,他们遇到了一个困难:有的树苗比较大,而有的位置挨太近,导致两棵树植下去后会撞在一起。
他们将树看成一个圆,圆心在他们找的位置上。如果两棵树对应的圆相交,这两棵树就不适合同时植下(相切不受影响),称为两棵树冲突。
小明和朋友们决定先合计合计,只将其中的一部分树植下去,保证没有互相冲突的树。他们同时希望这些树所能覆盖的面积和(圆面积和)最大。
输入格式
输入的第一行包含一个整数 n ,表示人数,即准备植树的位置数。
接下来 n 行,每行三个整数 x, y, r,表示一棵树在空地上的横、纵坐标和半径。
输出格式
输出一行包含一个整数,表示在不冲突下可以植树的面积和。由于每棵树的面积都是圆周率的整数倍,请输出答案除以圆周率后的值(应当是一个整数)。
样例输入
6
1 1 2
1 4 2
1 7 2
4 1 2
4 4 2
4 7 2
样例输出
12
思路:(我感觉我能做对一部分,欢迎批评指正)
package zzctst;
import java.util.Scanner;
public class tset09 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[][] arra = new int[n][3];
//存放能种下的树
int[][] tree = new int[n][3];
//接收树
for(int i = 0; i < arra.length; i++){
for(int j = 0; j < 3; j++){
arra[i][j] = in.nextInt();
}
}
f(arra, tree);
}
/**
* 统计能种下去的树的数量
* 保证两两之间的树aoe不相交,圆心之间的距离大于半径之和
* @param arra
*/
static void f(int[][] arra, int[][] tree){
//数量
int sum = 0;
//面积之和
int ans = 0;
//由大到小排序
sort(arra);
//空地先放一棵面积最大树
tree[0][0] = arra[0][0];
tree[0][1] = arra[0][1];
tree[0][2] = arra[0][2];
ans += tree[0][2] * tree[0][2];
sum++;
//
for(int i = 1; i < arra.length; i++){
boolean flag = true;
for(int j = 0; j < sum; j++){
//圆心之间的距离
double len = Math.sqrt(
(tree[j][0] - arra[i][0]) * (tree[j][0] - arra[i][0]) +
(tree[j][1] - arra[i][1]) * (tree[j][1] - arra[i][1])
);
//半径之和
double rSum = arra[i][2] + tree[j][2];
//判断圆心之间的距离小于半径之和
if(len < rSum){
flag = false;
break;
}
}
if(flag){
ans += arra[i][2] * arra[i][2];
tree[sum][0] = arra[i][0];
tree[sum][1] = arra[i][1];
tree[sum][2] = arra[i][2];
sum++;
}
}
System.out.println(ans);
}
/**
* 根据种下去的面积由大到小排序
* @param arra
*/
static void sort(int[][] arra){
for(int i = 0; i < arra.length - 1; i++){
for(int j = 0; j < arra.length - 1 - i; j++){
if(arra[j][2] < arra[j + 1][2]){
int temp = arra[j][0];
arra[j][0] = arra[j + 1][0];
arra[j+1][0] = temp;
temp = arra[j][1];
arra[j][1] = arra[j + 1][1];
arra[j+1][1] = temp;
temp = arra[j][2];
arra[j][2] = arra[j + 1][2];
arra[j+1][2] = temp;
}
}
}
}
}
第十题(最小生成树)
2015年,全中国实现了户户通电。作为一名电力建设者,小明正在帮助一带一路上的国家通电。
这一次,小明要帮助 n 个村庄通电,其中 1 号村庄正好可以建立一个发电站,所发的电足够所有村庄使用。
现在,这 n 个村庄之间都没有电线相连,小明主要要做的是架设电线连接这些村庄,使得所有村庄都直接或间接的与发电站相通。
小明测量了所有村庄的位置(坐标)和高度,如果要连接两个村庄,小明需要花费两个村庄之间的坐标距离加上高度差的平方,形式化描述为坐标为 (x_1, y_1) 高度为 h_1 的村庄与坐标为 (x_2, y_2) 高度为 h_2 的村庄之间连接的费用为
sqrt((x_1-x_2)(x_1-x_2)+(y_1-y_2)(y_1-y_2))+(h_1-h_2)*(h_1-h_2)。
在上式中 sqrt 表示取括号内的平方根。请注意括号的位置,高度的计算方式与横纵坐标的计算方式不同。
由于经费有限,请帮助小明计算他至少要花费多少费用才能使这 n 个村庄都通电。
输入格式
输入的第一行包含一个整数 n ,表示村庄的数量。
接下来 n 行,每个三个整数 x, y, h,分别表示一个村庄的横、纵坐标和高度,其中第一个村庄可以建立发电站。
输出格式
输出一行,包含一个实数,四舍五入保留 2 位小数,表示答案。
样例输入
4
1 1 3
9 9 7
8 8 6
4 5 4
样例输出
17.41