数列求值
本题总分:5 分
【问题描述】
给定数列 1, 1, 1, 3, 5, 9, 17, …,从第 4 项开始,每项都是前 3 项的和。求
第 20190324 项的最后 4 位数字。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个 4 位整数(提示:答案的千位不为 0),在提交答案时只填写这个整数,填写多余的内容将无法得分。
public class Main1 {
public static void main(String[] args) {
long a1 = 1;
long a2 = 1;
long a3 = 1;
long b = 0;
for (long i = 4; i <= 20190324; i++) {
b = (a1 + a2 + a3) % 10000;
long t = a3;
long p = a2;
a3 = b;
a2 = t;
a1 = p;
}
System.out.println(b);
}
}
给定一棵包含 N 个节点的完全二叉树,树上每个节点都有一个权值,按从 上到下、从左到右的顺序依次是 A1, A2, · · · AN,如下图所示:
现在小明要把相同深度的节点的权值加在一起,他想知道哪个深度的节点 权值之和最大?如果有多个深度的权值和同为最大,请你输出其中最小的深度。
注:根的深度是 1。
输入
第一行包含一个整数 N。 第二行包含N个整数A1,A2,··· AN。
输出
输出一个整数代表答案。
样例输入
7
1 6 5 4 3 2 1
样例输出
2
import java.math.BigInteger;
import java.util.Scanner;
public class Main1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] num = new int[n];
for (int i = 0; i < n; i++) {
num[i] = sc.nextInt();
}
// 最大权值和
BigInteger max = BigInteger.ZERO;
// 当前权值和
BigInteger cur = BigInteger.ZERO;
int deep = 1;
int index = 0;
for (int i = 1; i <= n; i++) {
cur = cur.add(new BigInteger(num[i - 1] + ""));
if (i == Math.pow(2, deep) - 1) {// 当前节点为本层最后一个
// 当前层权值和大于最大权值和
if (cur.compareTo(max) == 1) {
max = cur;
index = deep;
}
// 重置当前权值和
cur = BigInteger.ZERO;
deep++;// 下一层
}
}
System.out.println(index);
}
}
外卖店优先级
【问题描述】
“饱了么”外卖系统中维护着 N 家外卖店,编号 1 ∼ N。每家外卖店都有 一个优先级,初始时 (0 时刻) 优先级都为 0。 每经过 1 个时间单位,如果外卖店没有订单,则优先级会减少 1,最低减 到 0;而如果外卖店有订单,则优先级不减反加,每有一单优先级加 2。 如果某家外卖店某时刻优先级大于 5,则会被系统加入优先缓存中;如果 优先级小于等于 3,则会被清除出优先缓存。 给定 T 时刻以内的 M 条订单信息,请你计算 T 时刻时有多少外卖店在优 先缓存中。
【输入格式】
第一行包含 3 个整数 N、M 和 T。 以下 M 行每行包含两个整数 ts 和 id,表示 ts 时刻编号 id 的外卖店收到 一个订单。
【输出格式】
输出一个整数代表答案。
【样例输入】
2 6 6
1 1
5 2
3 1
6 2
2 1
6 2
【样例输出】
1
【样例解释】
6 时刻时,1 号店优先级降到 3,被移除出优先缓存;2 号店优先级升到 6, 加入优先缓存。所以是有 1 家店 (2 号) 在优先缓存中。
思路:直接模拟
参考自:2019第十届蓝桥杯省赛JavaA组题解
import java.util.ArrayList;
import java.util.Scanner;
public class Main2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int t = sc.nextInt();
// res[i][j]表示i时刻j店铺的优先值
int[][] res = new int[t + 1][n + 1];
int[] ids = new int[n];
int[] ts = new int[m];
for (int i = 0; i < m; i++) {
int key = sc.nextInt();
int value = sc.nextInt();
res[key][value] += 2;
}
int count = 0;
ArrayList<Integer> arrayList = new ArrayList<>();
for (int i = 1; i <= t; i++) {
for (int j = 1; j <= n; j++) {
if (res[i][j] == 0) {// 当前时刻没有订单
res[i][j] = (res[i - 1][j] - 1) > 0 ? (res[i - 1][j] - 1) : 0;
if (res[i][j] <= 3) {
if (arrayList.contains(j)) {
arrayList.remove((Object) j);
}
}
} else {
res[i][j] += res[i - 1][j];
if (res[i][j] > 5) {
if (!arrayList.contains(j)) {
arrayList.add(j);
}
}
}
}
}
System.out.println(arrayList.size());
}
}
修改数组
【问题描述】
给定一个长度为 N 的数组 A = [A1,A2,……,AN],数组中有可能有重复出现 的整数。
现在小明要按以下方法将其修改为没有重复整数的数组。小明会依次修改 A2,A3,··· ,AN。
当修改 Ai 时,小明会检查 Ai 是否在 A1 ∼ Ai−1 中出现过。如果出现过,则 小明会给 Ai 加上 1 ;如果新的 Ai 仍在之前出现过,小明会持续给 Ai 加 1 ,直 到 Ai 没有在 A1 ∼ Ai−1 中出现过。
当 AN 也经过上述修改之后,显然 A 数组中就没有重复的整数了。 现在给定初始的 A 数组,请你计算出最终的 A 数组。
【输入格式】
第一行包含一个整数 N。 第二行包含 N 个整数 A1,A2,··· ,AN 。
【输出格式】
输出 N 个整数,依次是最终的 A1,A2,··· ,AN。
【样例输入】
5
2 1 1 3 4
【样例输出】
2 1 3 4 5
思路:暴力循环,但超时了
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Main3 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] a = new int[n + 1];
Map<Integer, Integer> map = new HashMap<>();
for (int i = 1; i <= n; i++) {
a[i] = sc.nextInt();
}
for (int i = 2; i <= n; i++) {
int j = 1;
while (j < i) {
if (a[j] == a[i]) {
a[i]++;
j = 0;
}
j++;
}
}
for (int i = 1; i <= n; i++) {
System.out.print(a[i] + " ");
}
}
}
不同的子串:
一个字符串的非空子串是指字符串中长度至少为1 的连续的一段字符组成
的串。例如,字符串aaab 有非空子串a, b, aa, ab, aaa, aab, aaab,一共7 个。
注意在计算时,只算本质不同的串的个数。
请问,字符串0100110001010001 有多少个不同的非空子串?
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一
个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class Main4 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.next();
int i = 1;
Set<String> set = new HashSet<>();
while (i <= s.length()) {
for (int j = 0; j < s.length() && j + i <= s.length(); j++) {
set.add(s.substring(j, j + i));
}
i++;
}
System.out.println(set.size());
}
}
数的分解:
把2019 分解成3 个各不相同的正整数之和,并且要求每个正整数都不包
含数字2 和4,一共有多少种不同的分解方法?
注意交换3 个整数的顺序被视为同一种方法,例如1000+1001+18 和
1001+1000+18 被视为同一种。
public class Main5 {
public static void main(String[] args) {
int ans = 0;
for (int i = 1; i <= 2019; i++) {
for (int j = 1; j <= 2019; j++) {
if (j == i)
continue;
int k = 2019 - j - i;
if (k <= 0 || k == j || k == i)
continue;
if (check(i, j, k)) {
ans++;
}
}
}
System.out.println(ans / 6);
}
public static boolean check(int i, int j, int k) {
String s = "" + i + j + k;
if (s.indexOf("2") != -1 || s.indexOf("4") != -1) {
return false;
}
return true;
}
}
特别数的和:
小明对数位中含有2、0、1、9 的数字很感兴趣(不包括前导0),在1 到
40 中这样的数包括1、2、9、10 至32、39 和40,共28 个,他们的和是574。
请问,在1 到n 中,所有这样的数的和是多少?
输入:
输入一行包含一个整数n。
输出:
输出一行,包含一个整数,表示满足条件的数的和。
【样例输入】
40
【样例输出】
574
import java.util.Scanner;
public class Main6 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int sum = 0;
for (int i = 1; i <= n; i++) {
if (String.valueOf(i).indexOf("2") != -1 || String.valueOf(i).indexOf("0") != -1
|| String.valueOf(i).indexOf("1") != -1 || String.valueOf(i).indexOf("9") != -1) {
sum += i;
}
}
System.out.println(sum);
}
}
人物相关性分析:
【问题描述】
小明正在分析一本小说中的人物相关性。他想知道在小说中Alice 和Bob
有多少次同时出现。
更准确的说,小明定义Alice 和Bob“同时出现”的意思是:在小说文本
中Alice 和Bob 之间不超过K 个字符。
例如以下文本:
This is a story about Alice and Bob. Alice wants to send a private message to Bob.
假设K = 20,则Alice 和Bob 同时出现了2 次,分别是”Alice and Bob”
和”Bob. Alice”。前者Alice 和Bob 之间有5 个字符,后者有2 个字符。
注意:
Alice 和Bob 是大小写敏感的,alice 或bob 等并不计算在内。
Alice 和Bob 应为单独的单词,前后可以有标点符号和空格,但是不能
有字母。例如Bobbi 並不算出现了Bob。
【输入格式】
第一行包含一个整数K。
第二行包含一行字符串,只包含大小写字母、标点符号和空格。长度不超
过1000000。
【输出格式】
输出一个整数,表示Alice 和Bob 同时出现的次数。
【样例输入】
20
This is a story about Alice and Bob. Alice wants to send a private message to Bob.
【样例输出】
2
import java.util.Arrays;
import java.util.Scanner;
public class Main7 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int k = sc.nextInt();
sc.nextLine();
String s = sc.nextLine();
String[] word = s.split("\\s+|\\.");
int[] wordLength = new int[word.length];
for (int i = 0; i < word.length; i++) {
wordLength[i] = word[i].length();
}
int num = 0;// 记录结果
// Alice到Bob
for (int i = 0; i < word.length; i++) {
if (word[i].equals("Alice")) {
for (int j = i + 1; j < word.length; j++) {
int sum = 1;
if (word[j].equals("Bob")) {
for (int p = i + 1; p < j; p++) {
// 中间每个单词长度+空格长度
sum += wordLength[p] + 1;
}
if (sum <= k) {
num++;
}
}
}
}
}
// Bob到Alice
for (int i = 0; i < word.length; i++) {
if (word[i].equals("Bob")) {
for (int j = i + 1; j < word.length; j++) {
int sum = 1;
if (word[j].equals("Alice")) {
for (int p = i + 1; p < j; p++) {
// 中间每个单词长度+空格长度
sum += wordLength[p] + 1;
}
if (sum <= k) {
num++;
}
}
}
}
}
System.out.println(num);
}
}
质数
本题总分:10 分
【问题描述】
我们知道第一个质数是 2、第二个质数是 3、第三个质数是 5……请你计算 第 2019 个质数是多少?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
import java.util.Scanner;
public class Main9 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] prime = new int[100001];// 保存素数
boolean[] vis = new boolean[100001];// 标记数组,标记是否为素数的倍数
int cnt = 0;
for (int i = 2; i < 100001; i++) {
if (!vis[i]) {
prime[cnt++] = i;
}
for (int j = 0; j < cnt && i * prime[j] < 100001; j++) {
vis[i * prime[j]] = true;
// 避免重复标记
if (i % prime[j] == 0)
break;
}
}
System.out.println(prime[2018]);
}
}
图片旋转是对图片最简单的处理方式之一,在本题中,你需要对图片顺时 针旋转 90 度。
我们用一个 n × m 的二维数组来表示一个图片,例如下面给出一个 3 × 4 的 图片的例子:
1 3 5 7
9 8 7 6
3 5 9 7
这个图片顺时针旋转 90 度后的图片如下:
3 9 1
5 8 3
9 7 5
7 6 7
给定初始图片,请计算旋转后的图片
输入
输入的第一行包含两个整数 n 和 m,分别表示行数和列数。
接下来 n 行,每行 m 个整数,表示给定的图片。图片中的每个元素(像
素)为一个值为 0 至 255 之间的整数(包含 0 和 255)。
输出
输出 m 行 n 列,表示旋转后的图片。
样例输入
3 4
1 3 5 7
9 8 7 6
3 5 9 7
样例输出
3 9 1
5 8 3
9 7 5
7 6 7
import java.util.Scanner;
public class Main10 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int[][] a = new int[n][m];
int[][] b = new int[m][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
a[i][j] = sc.nextInt();
}
}
for (int j = 0; j < m; j++) {
for (int i = 0; i < n; i++) {
b[j][i] = a[n - 1 - i][j];
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
System.out.print(b[i][j] + " ");
}
System.out.println();
}
}
}
等差数列
时间限制: 1Sec 内存限制: 128MB
题目描述
数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一 部分的数列,只记得其中 N 个整数。
现在给出这 N 个整数,小明想知道包含这 N 个整数的最短的等差数列有 几项?
输入
输入的第一行包含一个整数 N。 第二行包含N个整数A1,A2,···,AN。(注意A1 ∼AN并不一定是按等差数
列中的顺序给出)
输出
输出一个整数表示答案
样例输入
5
2 6 4 10 20
样例输出
10
import java.util.Arrays;
import java.util.Scanner;
public class Main12 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
Arrays.sort(a);
int min = Integer.MAX_VALUE;
for (int i = 0; i < n - 1; i++) {
if (a[i + 1] - a[i] < min) {
min = a[i + 1] - a[i];
}
}
int cnt = 1;
int b = a[0];
while (b < a[n - 1]) {
b += min;
cnt++;
}
System.out.println(cnt);
}
}