所有答案均为个人想法 仅供参考,如有问题 欢迎指正
题目描述
小明设计了一种文章加密的方法:对于每个字母 c,将它变成某个另外的字符 Tc。下表给出了字符变换的规则:
例如,将字符串 YeRi 加密可得字符串 EaFn。
小明有一个随机的字符串,加密后为
EaFnjISplhFviDhwFbEjRjfIBBkRyY
(由 30 个大小写英文字母组成,不包含换行符),请问原字符串是多少?
(如果你把以上字符串和表格复制到文本文件中,请务必检查复制的内容
是否与文档中的一致。在试题目录下有一个文件 str.txt,第一行为上面的字符
串,后面 52 行依次为表格中的内容。)
【答案提交】
这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个
只包含 30 个大小写英文字母的字符串,在提交答案时只填写这个字符串,填写
多余的内容将无法得分。
个人答案:
YeRikGSunlRzgDlvRwYkXkrGWWhXaA
解题思路:
在表格中一个字母一个字母的找就可以了。
题目描述
2020 年 7 月 1 日是中国共产党成立 99 周年纪念日。
中国共产党成立于 1921 年 7 月 23 日。
请问从 1921 年 7 月 23 日中午 12 时到 2020 年 7 月 1 日中午 12 时一共包含多少分钟?
【答案提交】
这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个
整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
个人答案:
52038720
个人代码:
public class Main {
public static void main(String[] args) {
int[] mouth = {
0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int[] runMouth = {
0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
//1921年7月23号-31号的天数
int day = 31 - 23 + 1;
//1921年8月到12月的天数
for (int m = 8; m <= 12; ++m) {
if (runYear(1921)) {
day += runMouth[m];
} else {
day += mouth[m];
}
}
//从1922年-2019年的天数
for (int year = 1922; year <= 2019; ++year) {
for (int m = 1; m <= 12; ++m) {
if (runYear(year)) {
day += runMouth[m];
} else {
day += mouth[m];
}
}
}
//2020年1月-6月的天数
for (int m = 1; m <= 6; ++m) {
if (runYear(2020)) {
day += runMouth[m];
} else {
day += mouth[m];
}
}
System.out.println(day * 24 * 60);
}
//判断某年是不是闰年
public static boolean runYear(int year) {
return year%400==0||year%4==0&&year%100!=0;
}
}
36138 * 24 * 60=52038720
题目描述
新冠疫情由新冠病毒引起,最近在 A 国蔓延,为了尽快控制疫情,A 国准
备给大量民众进病毒核酸检测。
然而,用于检测的试剂盒紧缺。
为了解决这一困难,科学家想了一个办法:合并检测。即将从多个人(k个)采集的标本放到同一个试剂盒中进行检测。如果结果为阴性,则说明这 k个人都是阴性,用一个试剂盒完成了 k 个人的检测。如果结果为阳性,则说明至少有一个人为阳性,需要将这 k 个人的样本全部重新独立检测(从理论上看,如果检测前 k − 1 个人都是阴性可以推断出第 k 个人是阳性,但是在实际操作中不会利用此推断,而是将 k 个人独立检测),加上最开始的合并检测,一共使用了 k + 1 个试剂盒完成了 k 个人的检测。A 国估计被测的民众的感染率大概是 1%,呈均匀分布。请问 k 取多少能最节省试剂盒?
【答案提交】
这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
个人答案:
10
个人代码:
public class Main {
//因为是均匀分布的,不管一共有多少人,每100人里面就有一个呈现阳性
//设总人数为n,一共是 n/k组,有0.99*n/k个组呈阳性,有0.01*n/k各组成阴性
//总共需要的试剂盒个数为: 0.99*n/k+0.01*n/k*(k+1);
public static void main(String[] args) {
//假设一共有100人需要检测
int n = 100;
//假设当k=1的时候需要测试100次
int min = 100;
int mink = 1;
//分多少组
int group;
int temp;
for (int k = 2; k <= n; ++k) {
//向上取整
group = n % k == 0 ? n / k : n / k + 1;
//向上取整
int x = group * 0.99 > (int) (group * 0.99) ? (int) (group * 0.99) + 1 : (int) (group * 0.99);
int y = (group * 0.01 > (int) (group * 0.01) ? (int) (group * 0.01) + 1 : (int) (group * 0.01)) * (k + 1);
temp = x + y;
if (temp < min) {
min = temp;
mink = k;
}
}
System.out.println(mink);
}
}
题目描述
某市市长获得了若干批口罩,每一批口罩的数目如下:(如果你把以下文字复制到文本文件中,请务必检查复制的内容是否与文档中的一致。在试题目录下有一个文件
mask.txt,内容与下面的文本相同)
9090400
8499400
5926800
8547000
4958200
4422600
5751200
4175600
6309600
5865200
6604400
4635000
10663400
8087200
4554000
现在市长要把口罩分配给市内的 2 所医院。由于物流限制,每一批口罩只能全部分配给其中一家医院。市长希望 2
所医院获得的口罩总数之差越小越好。请你计算这个差最小是多少?
【答案提交】
这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
个人答案:
2400
个人代码:
public class Main {
static int middleMin = Integer.MAX_VALUE;
static int sumn = 0;
static int sum = 0;
static int min = 0;
public static void main(String[] args) {
int[] n = {
9090400, 8499400, 5926800, 8547000, 4958200, 4422600, 5751200, 4175600, 6309600, 5865200, 6604400, 4635000, 10663400, 8087200, 4554000};
int a = 0, b = 0;
for (int i = 0; i < n.length; ++i) {
sumn += n[i];
}
blackStacking(n, 0);
System.out.println(min);
}
//利用递归回溯,尝试所有的组合结果,找里中间值最近的那一个
static void blackStacking(int[] arr, int n) {
if (Math.abs(sumn / 2 - sum) < middleMin) {
middleMin = Math.abs(sumn / 2 - sum);
min = sumn - sum - sum;
}
for (int i = n; i < arr.length; ++i) {
sum += arr[i];
blackStacking(arr, i + 1);
sum -= arr[i];
}
}
}
个人答案:
6765
个人代码:
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
BigInteger[] b = new BigInteger[2021];
b[1] = new BigInteger(String.valueOf(1));
b[2] = new BigInteger(String.valueOf(1));
for (int i=3;i<2021;++i){
b[i]=b[i-1].add(b[i-2]);
}
BigInteger gcb = gcb(b[2020], b[520]);
System.out.println(gcb);
}
static BigInteger gcb(BigInteger x, BigInteger y) {
return x.remainder(y).intValue() == 0 ? y : gcb(y, x.remainder(y));
}
}
题目描述
输入一个字符串,请输出这个字符串包含多少个大写字母,多少个小写字母,多少个数字。
【输入格式】
输入一行包含一个字符串。
【输出格式】
输出三行,每行一个整数,分别表示大写字母、小写字母和数字的个数。
【样例输入】
1+a=Aab
【样例输出】
1
3
1
【评测用例规模与约定】
对于所有评测用例,字符串由可见字符组成,长度不超过 100。
个人代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
int up = 0;
int low = 0;
int num = 0;
for (int i = 0; i < s.length(); ++i) {
if (s.charAt(i) >= '0' && s.charAt(i) <= '9') {
num++;
} else if (s.charAt(i) >= 'A' && s.charAt(i) <= 'Z') {
up++;
} else if (s.charAt(i) >= 'a' && s.charAt(i) <= 'z') {
low++;
}
}
System.out.println(up);
System.out.println(low);
System.out.println(num);
}
}
【输入格式】
输入的第一行包含一个整数 n。
【输出格式】
输出一行,包含一个整数,表示答案。
【样例输入】
2
【样例输出】
257
【样例输入】
987654
【样例输出】
43636805
【评测用例规模与约定】
对于 20% 的评测用例,1 ≤ n ≤ 20。
对于 60% 的评测用例,1 ≤ n ≤ 1000。
对于所有评测用例,1 ≤ n ≤ 1000000。
个人代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
Long l = 0L;
Long temp = 1L;
for (int i = 1; i <= num; ++i) {
temp = 1L;
for (int j = 0; j < 8; ++j) {
temp = (temp * i)%123456789;
}
l =(l+temp)%123456789;
}
System.out.println(l);
}
}
题目描述
小明发明了一种给由全大写字母组成的字符串编码的方法。对于每一个大写字母,小明将它转换成它在 26 个英文字母中序号,即 A → 1, B → 2, … Z →26。这样一个字符串就能被转化成一个数字序列:比如 ABCXYZ → 123242526。现在给定一个转换后的数字序列,小明想还原出原本的字符串。当然这样的还原有可能存在多个符合条件的字符串。小明希望找出其中字典序最大的字
符串。
【输入格式】
一个数字序列。
【输出格式】
一个只包含大写字母的字符串,代表答案
【样例输入】
123242526
【样例输出】
LCXYZ
【评测用例规模与约定】
对于 20% 的评测用例,输入的长度不超过 20。
对于所有评测用例,输入的长度不超过 200000。
个人代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
char[] c = {
0, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
String str = "";
String s1;
for (int i = 0; i < s.length(); ++i) {
if (s.charAt(i) == '1' && i < s.length() - 1) {
s1 = s.charAt(i) + "" + s.charAt(i + 1);
str = str + c[Integer.parseInt(s1)];
i++;
} else if (s.charAt(i) == '2' && i < s.length() - 1 && s.charAt(i + 1) <= '6') {
s1 = s.charAt(i) + "" + s.charAt(i + 1);
str = str + c[Integer.parseInt(s1)];
i++;
} else {
str += c[s.charAt(i) - 48];
}
}
System.out.println(str);
}
}
题目描述
给定一棵包含 N 个节点的二叉树,节点编号是 1 ∼ N。其中 i 号节点具有权值 Wi,并且这些节点的权值恰好形成了一棵排序二叉树 (BST)。现在给定一个节点编号 K,小明想知道,在这 N 个权值以外,有多少个整数 X (即 X 不等于任何 Wi ) 满足:给编号为 K 的节点增加一个权值为 X 的子节点,仍可以得到一棵 BST。例如在下图中,括号外的数字表示编号、括号内的数字表示权值。编号1 ∼ 4 的节点权值依次是 0、10、20、30。
如果 K = 1,那么答案为 0。因为 1 号节点已经有左右子节点,不能再增加子节点了。
如果 K = 2,那么答案为无穷多。因为任何一个负数都可以作为 2 的左子节点。
如果 K = 3,那么答案为 9。因为 X = 11, 12, · · · , 19 都可以作为 3 的左子节点。
【输入格式】
第一行包含 2 个整数 N 和 K。
以下 N 行每行包含 2 个整数,其中第 i 行是编号为 i 的节点的父节点编号Pi 和权值 Wi 。注意 Pi = 0 表示 i 是根节点。输入保证是一棵 BST。
【输出格式】
一个整数代表答案。如果答案是无穷多,输出 −1。
【样例输入】
4 3
0 10
1 0
1 20
3 30
【样例输出】
9
【评测用例规模与约定】
对于 60% 的评测用例,1 ≤ K ≤ N ≤ 100,0 ≤ Wi ≤ 200,且 Wi 各不相同。
对于所有评测用例,1 ≤ K ≤ N ≤ 10000,0 ≤ Wi ≤ 100000000,且 Wi 各不相同。
个人代码:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
int[][] arr = new int[n + 1][2];
for (int i = 1; i < arr.length; ++i) {
for (int j = 0; j < arr[i].length; ++j) {
arr[i][j] = sc.nextInt();
}
sc.nextLine();
}
//初始化所有的结点
Node[] nodes = new Node[n + 1];
for (int i = 1; i < arr.length; ++i) {
nodes[i] = new Node(i, arr[i][1]);
}
//将结点构建成二叉树
for (int i = 1; i < arr.length; ++i) {
//只要当前结点不是根节点就有夫结点
if (arr[i][0] != 0) {
//如果当前结点的夫结点权值大于当前结点的权值,说明该结点是父节点的左子结点
if (nodes[arr[i][0]].weight > arr[i][1]) {
nodes[arr[i][0]].left = nodes[i];
}
//如果当前结点的夫结点权值小于当前结点的权值,说明该结点是父节点的右子结点
if (nodes[arr[i][0]].weight < arr[i][1]) {
nodes[arr[i][0]].right = nodes[i];
}
}
}
//获取k结点
Node nodeK = nodes[k];
int numer = 0;
boolean isFind = false;
while (!isFind) {
//如果当前结点的左右结点都有了就没有办法加了
if (nodeK.right != null && nodeK.left != null) {
break;
}
//如果当前结点的左节点为空,右结点不为空
//如果当前结点是父节点的左子树,那么numer=当前结点的右子树的权值-当前结点父节点的权值
//如果当前结点不是夫结点的左子树,那就需要一直向上找,如果找到根节点都没有找到的话就是无限多个
if (nodeK.left == null && nodeK.right != null) {
while (true) {
if (nodes[arr[k][0]].weight < nodeK.weight) {
numer = nodeK.weight - nodes[arr[k][0]].weight - 1;
isFind = true;
break;
}
if (nodes[arr[k][0]].id == 1) {
numer = -1;
isFind = true;
break;
}
arr[k][0] = arr[nodes[arr[k][0]].id][0];
}
}
//如果当前结点的右节点为空,左结点不为空和上面差不多
if (nodeK.left != null && nodeK.right == null) {
while (true) {
if (nodes[arr[k][0]].weight > nodeK.weight) {
numer = nodeK.weight - nodes[arr[k][0]].weight - 1;
isFind = true;
break;
}
if (nodes[arr[k][0]].id == 1) {
numer = -1;
isFind = true;
break;
}
arr[k][0] = arr[nodes[arr[k][0]].id][0];
}
}
//如果当前结点的左右结点都为空时
if (nodeK.left == null && nodeK.right == null) {
int x = 0, y = 0;
if (nodes[arr[k][0]].id == 1) {
numer = -1;
break;
}
if (nodes[arr[k][0]].left == nodeK) {
y = nodes[arr[k][0]].weight;
while (true) {
if (nodes[arr[k][0]].weight < nodeK.weight) {
x = nodes[arr[k][0]].weight;
break;
}
if (nodes[arr[k][0]].id == 1) {
numer = -1;
break;
}
arr[k][0] = arr[nodes[arr[k][0]].id][0];
}
} else if (nodes[arr[k][0]].right == nodeK) {
x = nodes[arr[k][0]].weight;
while (true) {
if (nodes[arr[k][0]].weight > nodeK.weight) {
y = nodes[arr[k][0]].weight;
break;
}
if (nodes[arr[k][0]].id == 1) {
numer = -1;
break;
}
arr[k][0] = arr[nodes[arr[k][0]].id][0];
}
}
if (numer != -1) {
numer = y - x - 1 - 1;
isFind = true;
break;
}
}
}
System.out.println(numer);
}
}
class Node {
int id;
int weight;
Node left;
Node right;
public Node(int id, int weight) {
this.id = id;
this.weight = weight;
}
}
题目描述
小明正在做一个网络实验。他设置了 n 台电脑,称为节点,用于收发和存储数据。初始时,所有节点都是独立的,不存在任何连接。小明可以通过网线将两个节点连接起来,连接后两个节点就可以互相通信了。两个节点如果存在网线连接,称为相邻。小明有时会测试当时的网络,他会在某个节点发送一条信息,信息会发送到每个相邻的节点,之后这些节点又会转发到自己相邻的节点,直到所有直接或间接相邻的节点都收到了信息。所有发送和接收的节点都会将信息存储下来。一条信息只存储一次。给出小明连接和测试的过程,请计算出每个节点存储信息的大小。
【输入格式】
输入的第一行包含两个整数 n, m,分别表示节点数量和操作数量。节点从1 至 n 编号。接下来 m 行,每行三个整数,表示一个操作。如果操作为 1 a b,表示将节点 a 和节点 b 通过网线连接起来。当 a = b时,表示连接了一个自环,对网络没有实质影响。如果操作为 2 p t,表示在节点 p 上发送一条大小为 t 的信息。
【输出格式】
输出一行,包含 n 个整数,相邻整数之间用一个空格分割,依次表示进行完上述操作后节点 1 至节点 n 上存储信息的大小。
【样例输入】
4 8
1 1 2
2 1 10
2 3 5
1 4 1
2 2 2
1 1 2
1 2 4
2 2 1
【样例输出】
13 13 5 3
【评测用例规模与约定】
对于 30% 的评测用例,1 ≤ n ≤ 20,1 ≤ m ≤ 100。
对于 50% 的评测用例,1 ≤ n ≤ 100,1 ≤ m ≤ 1000。
对于 70% 的评测用例,1 ≤ n ≤ 1000,1 ≤ m ≤ 10000。
对于所有评测用例,1 ≤ n ≤ 10000,1 ≤ m ≤ 100000,1 ≤ t ≤ 100。
个人代码:
//看别人的代码是用的 带权并查集,我不会用带权并查集 所以就写了这个简单的方法,时间可能长点 不过挺好理解的
import java.util.*;
public class Main {
//list集合用于保存 与某个点相连的所有点
static List<Integer> list = new ArrayList<>();
//队列 bfs的时候用于保存未遍历的点
static LinkedList<Integer> queue = new LinkedList<>();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int[][] op = new int[m][3];
//grap数组用于保存两个点是否相连,把点与点的相连转化为二维数组
int[][] grap = new int[n + 1][n + 1];
//保存每个点的信息
int[] src = new int[n + 1];
for (int i = 0; i < m; ++i) {
for (int j = 0; j < 3; ++j) {
op[i][j] = sc.nextInt();
}
sc.nextLine();
}
for (int i = 0; i < m; ++i) {
if (op[i][0] == 1) {
grap[op[i][1]][op[i][2]] = 1;
grap[op[i][2]][op[i][1]] = 1;
} else if (op[i][0] == 2) {
list.clear();
list.add(op[i][1]);
bfs(grap, op[i][1]);
for (Integer integer : list) {
src[integer] += op[i][2];
}
}
}
for (int i = 1; i < src.length; ++i) {
System.out.print(src[i] + " ");
}
}
//广度优先搜索,遍历跟n点相连的 所有点
public static void bfs(int[][] grap, int n) {
if (n > grap.length) {
return;
}
for (int i = 1; i < grap.length; ++i) {
if (grap[n][i] != 0) {
if (!list.contains(i)) {
list.add(i);
queue.add(i);
}
}
}
if (!queue.isEmpty()) {
bfs(grap, queue.poll());
}
}
}