提交 6c71fe22 编写于 作者: 每日一练社区's avatar 每日一练社区

add exercises

上级 9442e498
#### 问题描述
给定一棵包含 N 个节点的二叉树,节点编号是 1 ∼ N。其中 i 号节点具有权值 W i ,并且这些节点的权值恰好形成了一棵排序二叉树 (BST)。
现在给定一个节点编号 K,小明想知道,在这 N 个权值以外,有多少个整数 X (即 X 不等于任何 W i ) 满足:给编号为 K 的节点增加一个权值为 X 的子节点,仍可以得到一棵 BST。
例如在下图中,括号外的数字表示编号、括号内的数字表示权值。即编号1 ∼ 4 的节点权值依次是 0、10、20、30。
![](https://img-blog.csdnimg.cn/20201010210318917.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01pbGtMZW9uZw==,size_16,color_FFFFFF,t_70#pic_center)
如果 K = 1,那么答案为 0。因为 1 号节点已经有左右子节点,不能再增加子节点了。
如果 K = 2,那么答案为无穷多。因为任何一个负数都可以作为 2 的左子节点。
如果 K = 3,那么答案为 9。因为 X = 11,12,··· ,19 都可以作为 3 的左子节点。
#### 输入格式
第一行包含 2 个整数 N 和 K。
以下 N 行每行包含 2 个整数,其中第 i 行是编号为 i 的节点的父节点编号P i 和权值 W i 。注意 P i = 0 表示 i 是根节点。
输入保证是一棵 BST。
#### 输出格式
一个整数代表答案。如果答案是无穷多,输出 −1。
#### 样例输入
```
4 3
0 10
1 0
1 20
3 30
```
#### 样例输出
```
9
```
#### 评测用例规模与约定
对于 60% 的评测用例,1 ≤ K ≤ N ≤ 100,0 ≤ W i ≤ 200,且 W i 各不相同。
对于所有评测用例,1 ≤ K ≤ N ≤ 10000,0 ≤ W i ≤ 100000000,且 W i 各不相同。
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
public class _09BST插入节点问题 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
int[] parent = new int[n];
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i = 0; i < n; i++) {
parent[i] = sc.nextInt();
map.put(i + 1, sc.nextInt());
}
ArrayList<Integer> childs = new ArrayList<Integer>();
int rootWeight = map.get(1);
int kWeight = map.get(k);
for (int i = 0; i < parent.length; i++) {
if (k == parent[i])
childs.add(map.get(i + 1));
}
// 1.parents不存在的节点就是叶子节点,叶子节点的答案是无穷大
if (childs.size() == 0) {
System.out.println("叶子节点");
System.out.println(-1);
return;
}
// 2. 已经有左右孩子,答案是0
else if (childs.size() == 2) {
System.out.println("已经有左右孩子了");
System.out.println(0);
return;
}
// 3. 在右子树:k节点有左无右时为-1; 在左子树:k几点有右无左为-1
else if (childs.size() == 1 && (kWeight > rootWeight && childs.get(0) < kWeight)
|| (kWeight < rootWeight && childs.get(0) > kWeight)) {
System.out.println(-1);
return;
} else {
int fatherWeight = map.get(parent[k - 1]);
System.out.println(Math.abs(kWeight - fatherWeight) - 1);
return;
}
}
}
附件 prog.txt 中是一个用某种语言写的程序。附件在本文的末尾。
其中 REPEAT k 表示一个次数为 k 的循环。循环控制的范围由缩进表达,从次行开始连续的缩进比该行多的(前面的空白更长的)为循环包含的内容。
![](https://img-blog.csdnimg.cn/20210320200704647.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM0MDEzMjQ3,size_16,color_FFFFFF,t_70)
该片段中从 A = A + 4 所在的行到 A = A + 8 所在的行都在第一行的循环两次中。
REPEAT 6: 所在的行到 A = A + 7 所在的行都在 REPEAT 5: 循环中。
A = A + 5 实际总共的循环次数是 2 × 5 × 6 = 60 次。
请问该程序执行完毕之后,A 的值是多少?
题目给出的 prog.txt 文件:
```
A = 0
REPEAT 2:
A = A + 4
REPEAT 5:
REPEAT 6:
A = A + 5
A = A + 7
REPEAT 6:
A = A + 7
REPEAT 4:
A = A + 2
A = A + 7
A = A + 2
REPEAT 7:
REPEAT 4:
A = A + 8
A = A + 7
A = A + 4
A = A + 5
A = A + 8
REPEAT 8:
A = A + 5
REPEAT 1:
A = A + 2
REPEAT 7:
A = A + 5
A = A + 5
REPEAT 2:
REPEAT 3:
A = A + 1
A = A + 1
REPEAT 5:
A = A + 1
REPEAT 9:
REPEAT 6:
A = A + 5
A = A + 1
REPEAT 6:
A = A + 2
A = A + 8
A = A + 3
REPEAT 2:
A = A + 5
REPEAT 3:
A = A + 9
REPEAT 1:
A = A + 4
REPEAT 2:
A = A + 9
REPEAT 1:
A = A + 6
A = A + 6
A = A + 4
REPEAT 3:
A = A + 7
A = A + 1
REPEAT 2:
A = A + 3
REPEAT 5:
A = A + 2
A = A + 5
A = A + 2
A = A + 4
A = A + 3
REPEAT 4:
A = A + 4
A = A + 3
A = A + 7
REPEAT 5:
REPEAT 4:
A = A + 5
A = A + 7
REPEAT 5:
A = A + 3
REPEAT 3:
A = A + 3
A = A + 1
A = A + 8
A = A + 2
REPEAT 9:
A = A + 5
REPEAT 1:
A = A + 5
A = A + 2
A = A + 8
A = A + 6
REPEAT 3:
REPEAT 4:
A = A + 9
REPEAT 5:
A = A + 2
A = A + 1
REPEAT 9:
A = A + 9
A = A + 2
REPEAT 1:
A = A + 6
A = A + 8
REPEAT 2:
A = A + 9
A = A + 4
A = A + 7
REPEAT 2:
REPEAT 7:
A = A + 3
A = A + 5
REPEAT 3:
A = A + 5
A = A + 3
A = A + 6
A = A + 4
REPEAT 9:
A = A + 2
A = A + 8
A = A + 2
A = A + 3
REPEAT 2:
REPEAT 8:
A = A + 5
A = A + 1
A = A + 6
A = A + 1
A = A + 2
REPEAT 6:
REPEAT 1:
A = A + 3
REPEAT 1:
A = A + 2
REPEAT 4:
A = A + 7
A = A + 1
A = A + 8
REPEAT 6:
A = A + 5
REPEAT 6:
A = A + 3
REPEAT 2:
A = A + 2
A = A + 9
A = A + 7
REPEAT 9:
A = A + 8
REPEAT 9:
A = A + 8
A = A + 9
A = A + 3
A = A + 2
REPEAT 6:
A = A + 3
REPEAT 9:
A = A + 1
A = A + 9
A = A + 5
REPEAT 2:
A = A + 4
A = A + 9
A = A + 8
REPEAT 5:
A = A + 6
A = A + 9
A = A + 1
REPEAT 1:
A = A + 4
A = A + 2
REPEAT 9:
REPEAT 3:
A = A + 4
REPEAT 7:
A = A + 8
A = A + 3
REPEAT 5:
A = A + 9
REPEAT 8:
A = A + 9
A = A + 8
REPEAT 4:
A = A + 7
A = A + 7
A = A + 3
A = A + 5
REPEAT 6:
A = A + 7
REPEAT 7:
A = A + 2
A = A + 2
A = A + 1
REPEAT 8:
REPEAT 1:
REPEAT 4:
A = A + 6
A = A + 6
A = A + 2
REPEAT 5:
A = A + 4
A = A + 8
A = A + 4
REPEAT 1:
A = A + 5
REPEAT 7:
A = A + 8
REPEAT 6:
A = A + 4
A = A + 4
A = A + 8
REPEAT 4:
A = A + 2
REPEAT 2:
A = A + 4
REPEAT 2:
A = A + 3
REPEAT 1:
A = A + 2
A = A + 8
REPEAT 2:
A = A + 7
REPEAT 8:
A = A + 6
A = A + 1
A = A + 7
REPEAT 8:
A = A + 2
REPEAT 8:
REPEAT 6:
A = A + 1
A = A + 6
REPEAT 2:
A = A + 4
A = A + 1
A = A + 7
A = A + 4
REPEAT 4:
REPEAT 9:
A = A + 2
REPEAT 1:
A = A + 2
A = A + 5
REPEAT 8:
REPEAT 6:
A = A + 3
REPEAT 4:
A = A + 1
A = A + 6
A = A + 1
REPEAT 7:
A = A + 7
REPEAT 7:
A = A + 3
A = A + 9
A = A + 1
A = A + 9
REPEAT 3:
A = A + 5
A = A + 5
A = A + 6
A = A + 2
REPEAT 1:
A = A + 4
REPEAT 2:
A = A + 7
REPEAT 1:
A = A + 7
REPEAT 4:
A = A + 7
A = A + 2
REPEAT 5:
A = A + 9
A = A + 1
A = A + 9
A = A + 5
A = A + 9
REPEAT 5:
A = A + 5
REPEAT 1:
A = A + 6
REPEAT 2:
A = A + 3
A = A + 2
A = A + 6
A = A + 8
A = A + 8
A = A + 7
A = A + 5
A = A + 5
REPEAT 2:
A = A + 1
A = A + 7
A = A + 3
REPEAT 2:
A = A + 7
A = A + 1
A = A + 4
REPEAT 1:
REPEAT 7:
REPEAT 2:
A = A + 3
A = A + 5
A = A + 2
A = A + 6
A = A + 1
A = A + 2
A = A + 4
A = A + 9
REPEAT 1:
A = A + 8
REPEAT 8:
REPEAT 4:
REPEAT 8:
A = A + 4
REPEAT 3:
A = A + 1
A = A + 8
REPEAT 7:
A = A + 8
REPEAT 7:
A = A + 7
A = A + 7
REPEAT 7:
A = A + 6
REPEAT 5:
A = A + 9
A = A + 3
REPEAT 4:
A = A + 5
A = A + 5
A = A + 4
REPEAT 9:
REPEAT 3:
A = A + 4
A = A + 3
A = A + 6
REPEAT 1:
A = A + 3
A = A + 3
A = A + 6
REPEAT 6:
A = A + 7
A = A + 7
A = A + 5
A = A + 5
A = A + 1
A = A + 2
A = A + 6
A = A + 6
REPEAT 9:
A = A + 6
REPEAT 1:
REPEAT 2:
A = A + 4
A = A + 7
REPEAT 3:
A = A + 6
REPEAT 5:
A = A + 3
A = A + 6
REPEAT 9:
A = A + 3
A = A + 6
REPEAT 5:
A = A + 8
A = A + 8
REPEAT 3:
A = A + 7
A = A + 9
A = A + 8
A = A + 3
A = A + 3
A = A + 9
REPEAT 6:
A = A + 9
A = A + 1
REPEAT 4:
REPEAT 1:
A = A + 7
REPEAT 9:
A = A + 2
A = A + 9
A = A + 1
A = A + 2
A = A + 8
A = A + 7
A = A + 9
A = A + 6
REPEAT 4:
REPEAT 2:
A = A + 3
REPEAT 3:
A = A + 4
A = A + 4
REPEAT 6:
A = A + 6
A = A + 1
A = A + 5
A = A + 8
REPEAT 2:
A = A + 6
REPEAT 1:
REPEAT 2:
A = A + 2
REPEAT 3:
A = A + 1
REPEAT 1:
A = A + 8
A = A + 7
A = A + 4
A = A + 2
A = A + 8
A = A + 4
REPEAT 5:
REPEAT 6:
A = A + 8
REPEAT 9:
A = A + 5
A = A + 5
REPEAT 5:
A = A + 5
REPEAT 3:
REPEAT 5:
A = A + 4
REPEAT 4:
A = A + 6
A = A + 3
REPEAT 7:
A = A + 3
A = A + 3
A = A + 1
A = A + 7
A = A + 7
A = A + 6
A = A + 5
A = A + 5
A = A + 6
REPEAT 1:
A = A + 9
A = A + 3
REPEAT 1:
REPEAT 1:
A = A + 1
REPEAT 8:
A = A + 5
REPEAT 8:
A = A + 6
REPEAT 4:
A = A + 9
A = A + 4
REPEAT 2:
A = A + 3
A = A + 7
REPEAT 5:
A = A + 7
A = A + 5
A = A + 8
A = A + 7
A = A + 8
A = A + 5
REPEAT 2:
A = A + 5
A = A + 7
A = A + 8
A = A + 5
A = A + 9
REPEAT 2:
REPEAT 6:
A = A + 9
A = A + 1
A = A + 8
A = A + 7
A = A + 1
A = A + 5
REPEAT 3:
A = A + 3
A = A + 9
A = A + 7
REPEAT 3:
A = A + 9
A = A + 1
REPEAT 6:
A = A + 1
REPEAT 9:
REPEAT 7:
A = A + 3
REPEAT 5:
A = A + 5
A = A + 8
A = A + 8
A = A + 1
A = A + 2
REPEAT 4:
A = A + 6
REPEAT 3:
A = A + 3
A = A + 7
REPEAT 8:
REPEAT 1:
A = A + 7
A = A + 8
A = A + 3
A = A + 1
A = A + 2
A = A + 4
A = A + 7
REPEAT 1:
REPEAT 1:
REPEAT 1:
A = A + 4
A = A + 6
REPEAT 1:
A = A + 3
A = A + 9
A = A + 6
REPEAT 9:
A = A + 1
A = A + 6
REPEAT 5:
A = A + 3
A = A + 9
A = A + 5
A = A + 5
A = A + 7
A = A + 2
REPEAT 2:
A = A + 7
A = A + 7
REPEAT 7:
REPEAT 4:
A = A + 6
A = A + 8
REPEAT 6:
A = A + 6
REPEAT 2:
A = A + 1
A = A + 7
A = A + 6
A = A + 7
REPEAT 4:
REPEAT 7:
A = A + 1
REPEAT 2:
A = A + 2
A = A + 5
A = A + 8
A = A + 2
A = A + 1
A = A + 4
REPEAT 8:
A = A + 5
A = A + 6
REPEAT 7:
REPEAT 6:
REPEAT 9:
A = A + 7
A = A + 8
REPEAT 4:
A = A + 6
A = A + 4
A = A + 3
A = A + 6
REPEAT 9:
A = A + 3
REPEAT 9:
A = A + 2
A = A + 7
A = A + 5
A = A + 2
REPEAT 7:
REPEAT 8:
REPEAT 6:
A = A + 4
A = A + 9
A = A + 5
A = A + 3
A = A + 9
REPEAT 4:
REPEAT 1:
A = A + 6
A = A + 8
REPEAT 1:
A = A + 6
A = A + 4
A = A + 6
REPEAT 3:
A = A + 7
REPEAT 3:
A = A + 4
A = A + 4
A = A + 2
A = A + 3
A = A + 7
REPEAT 5:
A = A + 6
A = A + 5
REPEAT 1:
REPEAT 8:
A = A + 5
REPEAT 3:
A = A + 6
REPEAT 9:
A = A + 4
A = A + 3
REPEAT 6:
REPEAT 2:
A = A + 1
A = A + 5
A = A + 2
A = A + 2
A = A + 7
REPEAT 4:
A = A + 7
A = A + 9
A = A + 2
REPEAT 8:
A = A + 9
REPEAT 9:
REPEAT 2:
A = A + 3
A = A + 2
A = A + 1
A = A + 5
REPEAT 9:
A = A + 1
A = A + 3
A = A + 9
REPEAT 7:
A = A + 2
REPEAT 5:
A = A + 9
A = A + 3
REPEAT 2:
A = A + 4
REPEAT 8:
A = A + 9
REPEAT 5:
A = A + 5
A = A + 4
A = A + 2
A = A + 4
REPEAT 6:
A = A + 2
REPEAT 5:
A = A + 7
A = A + 7
A = A + 8
A = A + 3
REPEAT 8:
A = A + 2
A = A + 5
REPEAT 1:
A = A + 8
A = A + 5
A = A + 1
A = A + 1
A = A + 5
REPEAT 2:
A = A + 6
REPEAT 6:
A = A + 9
A = A + 2
A = A + 5
REPEAT 4:
A = A + 7
A = A + 1
REPEAT 6:
A = A + 8
A = A + 4
REPEAT 3:
REPEAT 2:
A = A + 1
A = A + 5
REPEAT 2:
A = A + 7
REPEAT 9:
A = A + 6
A = A + 8
A = A + 9
A = A + 5
REPEAT 9:
REPEAT 3:
A = A + 7
A = A + 7
A = A + 9
A = A + 7
REPEAT 5:
A = A + 7
A = A + 2
A = A + 1
A = A + 8
A = A + 3
A = A + 5
A = A + 1
REPEAT 8:
A = A + 4
A = A + 2
A = A + 2
A = A + 8
REPEAT 4:
REPEAT 4:
A = A + 8
REPEAT 7:
A = A + 5
A = A + 2
REPEAT 2:
A = A + 6
REPEAT 4:
A = A + 8
A = A + 6
A = A + 1
A = A + 3
A = A + 2
A = A + 7
A = A + 4
REPEAT 8:
A = A + 2
A = A + 4
REPEAT 5:
REPEAT 3:
REPEAT 6:
A = A + 8
A = A + 1
A = A + 6
A = A + 5
A = A + 9
REPEAT 8:
A = A + 7
REPEAT 6:
A = A + 4
A = A + 5
REPEAT 3:
A = A + 1
REPEAT 1:
REPEAT 5:
A = A + 6
A = A + 2
REPEAT 9:
REPEAT 5:
A = A + 9
A = A + 3
REPEAT 9:
A = A + 9
A = A + 8
REPEAT 8:
REPEAT 5:
A = A + 9
A = A + 4
REPEAT 9:
A = A + 3
A = A + 4
A = A + 5
REPEAT 9:
REPEAT 7:
A = A + 5
REPEAT 3:
A = A + 7
REPEAT 9:
REPEAT 6:
A = A + 4
A = A + 6
REPEAT 5:
REPEAT 6:
A = A + 5
A = A + 3
A = A + 3
A = A + 3
A = A + 5
REPEAT 7:
A = A + 5
REPEAT 2:
A = A + 5
A = A + 6
REPEAT 2:
A = A + 2
A = A + 5
A = A + 3
A = A + 5
A = A + 5
REPEAT 4:
A = A + 2
A = A + 1
REPEAT 9:
A = A + 9
A = A + 5
A = A + 6
A = A + 2
A = A + 2
A = A + 5
REPEAT 9:
A = A + 5
A = A + 4
REPEAT 4:
REPEAT 4:
A = A + 1
A = A + 2
REPEAT 6:
A = A + 9
A = A + 3
REPEAT 2:
A = A + 5
A = A + 1
A = A + 1
A = A + 3
A = A + 8
REPEAT 7:
A = A + 4
REPEAT 6:
A = A + 9
REPEAT 5:
A = A + 9
A = A + 8
A = A + 3
A = A + 9
A = A + 4
A = A + 6
REPEAT 7:
A = A + 9
REPEAT 9:
A = A + 4
A = A + 9
A = A + 1
A = A + 3
REPEAT 5:
REPEAT 1:
A = A + 4
A = A + 4
REPEAT 8:
A = A + 9
A = A + 6
A = A + 2
REPEAT 3:
A = A + 4
A = A + 4
REPEAT 3:
A = A + 5
A = A + 2
A = A + 8
A = A + 3
A = A + 6
A = A + 4
A = A + 9
A = A + 1
A = A + 9
A = A + 5
A = A + 3
REPEAT 3:
A = A + 2
A = A + 5
A = A + 8
A = A + 2
A = A + 5
REPEAT 8:
REPEAT 2:
A = A + 6
A = A + 7
A = A + 6
A = A + 9
A = A + 2
REPEAT 2:
A = A + 3
REPEAT 8:
A = A + 7
A = A + 2
A = A + 1
A = A + 4
A = A + 1
A = A + 5
A = A + 2
A = A + 1
REPEAT 1:
A = A + 1
REPEAT 6:
A = A + 4
A = A + 3
A = A + 3
REPEAT 5:
A = A + 3
REPEAT 6:
REPEAT 1:
A = A + 5
A = A + 7
A = A + 7
A = A + 7
REPEAT 5:
A = A + 9
A = A + 7
REPEAT 5:
A = A + 9
A = A + 1
A = A + 9
A = A + 8
REPEAT 1:
A = A + 2
REPEAT 5:
A = A + 8
REPEAT 3:
A = A + 2
A = A + 9
A = A + 6
A = A + 3
REPEAT 5:
REPEAT 6:
A = A + 5
A = A + 5
REPEAT 4:
A = A + 5
A = A + 4
REPEAT 8:
A = A + 9
A = A + 1
REPEAT 8:
A = A + 8
A = A + 1
A = A + 4
REPEAT 6:
A = A + 6
REPEAT 2:
A = A + 3
A = A + 9
A = A + 6
A = A + 9
REPEAT 1:
A = A + 4
REPEAT 3:
A = A + 3
A = A + 4
A = A + 2
A = A + 8
REPEAT 2:
A = A + 4
A = A + 1
REPEAT 9:
A = A + 2
A = A + 9
A = A + 7
REPEAT 7:
REPEAT 7:
REPEAT 5:
A = A + 7
REPEAT 5:
A = A + 1
A = A + 1
REPEAT 5:
A = A + 6
REPEAT 1:
A = A + 4
REPEAT 9:
A = A + 4
A = A + 1
REPEAT 6:
A = A + 8
A = A + 5
REPEAT 1:
A = A + 4
REPEAT 5:
A = A + 8
A = A + 7
A = A + 2
REPEAT 3:
A = A + 3
REPEAT 8:
REPEAT 8:
A = A + 4
A = A + 7
REPEAT 5:
A = A + 1
REPEAT 8:
A = A + 7
A = A + 8
A = A + 4
A = A + 7
A = A + 6
A = A + 9
A = A + 5
REPEAT 3:
A = A + 5
REPEAT 9:
A = A + 1
A = A + 7
REPEAT 1:
A = A + 8
A = A + 4
REPEAT 8:
REPEAT 7:
A = A + 2
REPEAT 4:
A = A + 6
A = A + 6
REPEAT 1:
A = A + 7
A = A + 1
REPEAT 9:
REPEAT 5:
A = A + 6
A = A + 5
REPEAT 7:
A = A + 3
A = A + 6
A = A + 8
REPEAT 2:
A = A + 7
A = A + 1
A = A + 9
REPEAT 3:
REPEAT 3:
A = A + 5
```
\ No newline at end of file
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;
char mp[N][N];
int s[N], t[N], top;
int main()
{
FILE *fp;
fp = fopen("prog.txt", "r"); ///文件读操作
char ch;
int tot = 0;
int i = 0;
while ((ch = fgetc(fp)) != EOF) ///一个字符一个字符的读入
{
if (ch == '\n')
{
mp[tot][i] = '\0';
tot++;
i = 0;
continue;
}
mp[tot][i++] = ch;
}
/*
for(int i=0;i<tot;i++)
printf("%s\n",mp[i]);*/
///将txt中的数据已经全部保存在了mp数组中
top = 0;
int p, w = 1, sum = 0;
s[top] = -1, t[top] = -1; ///防止栈空的时候进行出栈操作
for (int i = 0; i < tot; i++)
{
int len = strlen(mp[i]);
p = 0;
while (mp[i][p] == ' ') ///统计缩进
p++;
while (s[top] >= p) ///开始新的循环,上一层的循环不包括
w /= t[top--];
if (mp[i][len - 1] == ':') ///当前是循环语句
{
int num = mp[i][len - 2] - '0';
top++;
w *= num; ///累计循环了几次
s[top] = p, t[top] = num; ///第top层循环语句的缩进量和循环次数
}
else
{
int num = mp[i][len - 1] - '0';
sum += w * num;
}
}
printf("%d\n", sum);
return 0;
}
RSA是一种经典的加密算法。它的基本加密过程如下。
首先生成两个质数p,q, 令$n = p \cdot q$,设d与$(p-1) \cdot (q-1)$互质,则可以找到e,使得$d \cdot e$除以$(p-1) \cdot (q-1)$的余数为1
n,d,e组成了私钥,n,d构成了公钥。
当使用公钥加密一个整数X时(X<=n-1),计算$C = X^d$ mod n,则C是加密后的密文。
当收到密文C时,可以使用私钥解开,计算公式为:$X = C^e$ mod n。
例如:当p = 5, q = 11, n = 55, e = 27。
若加密数字24,得$24^3$ % 55 = 19。
解密数字19,得$19^{27}$ % 55 = 24。
现在你知道公钥中n = 1001733993063167141,d = 212353,同时,你截获了别人发送的密文C = 20190324,请问,原文是多少?
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn = 1e8 + 10;
const LL n = 1001733993063167141ll;
const LL p = 891234941ll;
const LL q = 1123984201ll;
const LL d = 212353;
const LL c = 20190324;
int a[maxn];
int sushu[maxn / 10];
bool notPrime[maxn]; ///筛素数分解不出来,目测是9位数*10位数
int cnt;
void getPrime(int n)
{
for (int i = 2; i <= n; ++i)
{
if (!notPrime[i])
sushu[cnt++] = i;
for (int j = 0; j < cnt && 1ll * i * sushu[j] <= n; ++j)
{
notPrime[i * sushu[j]] = true;
if (i % sushu[j] == 0)
break;
}
}
for (int i = 0; i < 20; ++i)
cout << sushu[i] << " ";
cout << endl;
}
void fenjie(LL x)
{
cout << x << " = 1";
for (int i = 0; i < cnt && sushu[i] <= x / sushu[i]; ++i)
{
while (x % sushu[i] == 0)
{
cout << " * " << sushu[i];
x /= sushu[i];
}
}
if (x > 1)
cout << " * " << x;
cout << endl;
}
void BF(LL x)
{
cout << x << " = ";
for (LL i = 1e8 + 1; i < x; i += 2)
{
if (x % i == 0)
cout << i << " * ", x /= i;
}
cout << x << endl;
}
void exgcd(LL a, LL b, LL &d, LL &x, LL &y)
{
if (b == 0)
{
d = a;
x = 1;
y = 0;
return;
}
exgcd(b, a % b, d, y, x);
y -= (a / b) * x;
}
LL rev(LL t, LL m)
{
LL d, x, y;
exgcd(t, m, d, x, y);
return (x % m + m) % m;
}
LL fast_product(LL a, LL b, LL mod)
{
LL ans = 0;
while (b)
{
if (b & 1)
ans = (ans + a) % mod;
a = (a + a) % mod;
b >>= 1;
}
return ans;
}
LL fast_pow(LL a, LL b, LL mod)
{
LL ans = 1;
while (b)
{
if (b & 1)
ans = fast_product(ans, a, mod);
a = fast_product(a, a, mod);
b >>= 1;
}
return ans;
}
int main()
{
//getPrime(maxn-5);
//fenjie(n);
BF(n);
LL y = (p - 1) * (q - 1);
LL e = rev(d, y);
LL answer = fast_pow(c, e, n);
cout << answer << endl;
return 0;
}
#### 问题描述
给定一个长度为N的数列,$A_1, A_2, … A_N,$如果其中一段连续的子序列$A_i, A_{i+1}, … A_j(i <= j)$之和是K的倍数,我们就称这个区间[i, j]是K倍区间。
你能求出数列中总共有多少个K倍区间吗?
#### 输入格式
第一行包含两个整数N和K。(1 <= N, K <= 100000)
以下N行每行包含一个整数$A_i$。(1 <= $A_i$ <= 100000)
#### 输出格式
输出一个整数,代表K倍区间的数目。
#### 样例输入
```
5 2
1
2
3
4
5
```
#### 样例输出
```
6
```
\ No newline at end of file
#include <bits/stdc++.h>
using namespace std;
int main()
{
long long n, k, ans = 0, son[100000], sum[100000], b[100000] = {0};
cin >> n >> k;
for (int i = 0; i < n; i++)
{
cin >> son[i];
if (i != 0)
sum[i] = (sum[i - 1] + son[i]) % k;
else
sum[i] = son[i] % k;
b[sum[i]]++;
ans += b[sum[i]] - 1;
if (sum[i] == 0)
ans++;
}
cout << ans;
return 0;
}
\ No newline at end of file
{
"node_id": "569d5e11c4fc5de7844053d9a733c5e8",
"keywords": [],
"children": [],
"export": []
}
\ No newline at end of file
#### 题目描述
三体人将对地球发起攻击。为了抵御攻击,地球人派出了 A × B × C 艘战舰,在太空中排成一个 A 层 B 行 C 列的立方体。其中,第 i 层第 j 行第 k 列的战舰(记为战舰 (i, j, k))的生命值为 d(i, j, k)。
三体人将会对地球发起 m 轮“立方体攻击”,每次攻击会对一个小立方体中的所有战舰都造成相同的伤害。具体地,第 t 轮攻击用 7 个参数 $la_t, ra_t, lb_t, rb_t, lc_t, rc_t, h_t $描述;
所有满足$ i ∈ [la_t, ra_t],j ∈ [lb_t, rb_t],k ∈ [lc_t, rc_t] $的战舰 (i, j, k) 会受到 $h_t$ 的伤害。如果一个战舰累计受到的总伤害超过其防御力,那么这个战舰会爆炸。
地球指挥官希望你能告诉他,第一艘爆炸的战舰是在哪一轮攻击后爆炸的。
#### 输入格式
从标准输入读入数据。
第一行包括 4 个正整数 A, B, C, m;
第二行包含 A × B × C 个整数,其中第 ((i − 1)×B + (j − 1)) × C + (k − 1)+1 个数为 d(i, j, k);
第 3 到第 m + 2 行中,第 (t − 2) 行包含 7 个正整数 $la_t, ra_t, lb_t, rb_t, lc_t, rc_t, h_t$。
#### 输出格式
输出到标准输出。
输出第一个爆炸的战舰是在哪一轮攻击后爆炸的。保证一定存在这样的战舰。
#### 样例输入
```
2 2 2 3
1 1 1 1 1 1 1 1
1 2 1 2 1 1 1
1 1 1 2 1 2 1
1 1 1 1 1 1 2
```
#### 样例输出
```
2
```
#### 样例解释
在第 2 轮攻击后,战舰 (1,1,1) 总共受到了 2 点伤害,超出其防御力导致爆炸。
#### 数据约定
```
对于 10% 的数据,B = C = 1;
对于 20% 的数据,C = 1;
对于 40% 的数据,A × B × C, m ≤ 10, 000;
对于 70% 的数据,A, B, C ≤ 200;
对于所有数据,A × B × C ≤ 10^6, m ≤ 10^6, 0 ≤ d(i, j, k), ht ≤ 10^9。
```
\ No newline at end of file
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 2000010;
typedef long long LL;
int A, B, C, m;
LL s[N], b[N], bp[N];
int op[N / 2][7];
const int d[8][4] = {
{0, 0, 0, 1},
{0, 0, 1, -1},
{0, 1, 0, -1},
{0, 1, 1, 1},
{1, 0, 0, -1},
{1, 0, 1, 1},
{1, 1, 0, 1},
{1, 1, 1, -1}};
int get(int i, int j, int k)
{
return (i * B + j) * C + k;
}
bool check(int mid)
{
memcpy(b, bp, sizeof bp);
for (int i = 1; i <= mid; i++)
{
int x1 = op[i][0], x2 = op[i][1], y1 = op[i][2], y2 = op[i][3], z1 = op[i][4], z2 = op[i][5], h = op[i][6];
b[get(x1, y1, z1)] -= h;
b[get(x1, y1, z2 + 1)] += h;
b[get(x1, y2 + 1, z1)] += h;
b[get(x1, y2 + 1, z2 + 1)] -= h;
b[get(x2 + 1, y1, z1)] += h;
b[get(x2 + 1, y1, z2 + 1)] -= h;
b[get(x2 + 1, y2 + 1, z1)] -= h;
b[get(x2 + 1, y2 + 1, z2 + 1)] += h;
}
memset(s, 0, sizeof s);
for (int i = 1; i <= A; i++)
for (int j = 1; j <= B; j++)
for (int k = 1; k <= C; k++)
{
s[get(i, j, k)] = b[get(i, j, k)];
for (int u = 1; u < 8; u++)
{
int x = i - d[u][0], y = j - d[u][1], z = k - d[u][2], t = d[u][3];
s[get(i, j, k)] -= s[get(x, y, z)] * t;
}
if (s[get(i, j, k)] < 0)
return true;
}
return false;
}
int main()
{
scanf("%d%d%d%d", &A, &B, &C, &m);
for (int i = 1; i <= A; i++)
for (int j = 1; j <= B; j++)
for (int k = 1; k <= C; k++)
scanf("%lld", &s[get(i, j, k)]);
for (int i = 1; i <= A; i++)
for (int j = 1; j <= B; j++)
for (int k = 1; k <= C; k++)
for (int u = 0; u < 8; u++)
{
int x = i - d[u][0], y = j - d[u][1], z = k - d[u][2], t = d[u][3];
bp[get(i, j, k)] += s[get(x, y, z)] * t;
}
for (int i = 1; i <= m; i++)
for (int j = 0; j < 7; j++)
scanf("%d", &op[i][j]);
int l = 1, r = m;
while (l < r)
{
int mid = l + r >> 1;
if (check(mid))
r = mid;
else
l = mid + 1;
}
printf("%d\n", r);
return 0;
}
观察下面的加法算式:
![](https://img-blog.csdnimg.cn/20200323231451860.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkxMDMyMA==,size_16,color_FFFFFF,t_70#pic_center)
其中,相同的汉字代表相同的数字,不同的汉字代表不同的数字。
请你填写“三羊献瑞”所代表的4位数字(答案唯一)
\ No newline at end of file
#include <iostream>
#include <algorithm>
using namespace std;
int a[10];
int main()
{
for (int i = 0; i < 10; i++)
a[i] = i;
do
{
if (!a[0] || !a[4])
continue; //祥、三不能为0
int t1 = a[0] * 1000 + a[1] * 100 + a[2] * 10 + a[3]; //祥瑞生辉
int t2 = a[4] * 1000 + a[5] * 100 + a[6] * 10 + a[1]; //三羊献瑞
int t3 = a[4] * 10000 + a[5] * 1000 + a[2] * 100 + a[1] * 10 + a[7]; //三羊生瑞气
if (t1 + t2 == t3)
{
cout << t2;
break;
}
} while (next_permutation(a, a + 10));
return 0;
}
已知三角形三个顶点在直角坐标系下的坐标分别为:
```
(2.3,2.5)
(6.4,3.1)
(5.1,7.2)
```
求该三角形的面积。
\ No newline at end of file
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef pair<double, double> PDD;
#define x first
#define y second
double cross(double x1, double y1, double x2, double y2)
{
return x1 * y2 - x2 * y1;
}
int main()
{
PDD pts[3];
for (int i = 0; i < 3; i++)
{
scanf("%lf%lf", &pts[i].first, &pts[i].second);
}
cout << 0.5 * cross(pts[1].x - pts[0].x, pts[1].y - pts[0].y, pts[2].x - pts[0].x, pts[2].y - pts[0].y) << endl;
return 0;
}
一般的排序有许多经典算法,如快速排序、希尔排序等。但实际应用时,经常会或多或少有一些特殊的要求。我们没必要套用那些经典算法,可以根据实际情况建立更好的解法。
比如,对一个整型数组中的数字进行分类排序:
使得负数都靠左端,正数都靠右端,0在中部。注意问题的特点是:负数区域和正数区域内并不要求有序。可以利用这个特点通过1次线性扫描就结束战斗!!
以下的程序实现了该目标。
其中x指向待排序的整型数组,len是数组的长度。
#include <iostream>
using namespace std;
void sort3p(int *x, int len)
{
int p = 0;
int left = 0;
int right = len - 1;
while (p <= right)
{
if (x[p] < 0)
{
int t = x[left];
x[left] = x[p];
x[p] = t;
left++;
p++;
}
else if (x[p] > 0)
{
int t = x[right];
x[right] = x[p];
x[p] = t;
right--;
}
else
{
p++; //填空位置
}
}
}
int main()
{
int a[10] = {0, -1, 0, 0, -2, 5, 3, 1, 0, 7};
sort3p(a, 10);
for (int i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
return 0;
}
\ No newline at end of file
曾有邪教称1999年12月31日是世界末日。当然该谣言已经不攻自破。
还有人称今后的某个世纪末的12月31日,如果是星期一则会....
有趣的是,任何一个世纪末的年份的12月31日都不可能是星期一!!
于是,“谣言制造商”又修改为星期日......
1999年的12月31日是星期五,请问:未来哪一个离我们最近的一个世纪末年(即xx99年)的12月31日正好是星期天(即星期日)?
请回答该年份(只写这个4位整数,不要写12月31等多余信息)
#include <iostream>
using namespace std;
int main()
{
long long sum = 0;
for (int i = 2000;; i++)
{
sum += (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) ? 366 : 365;
if (i % 100 == 99 && sum % 7 == 2)
{
cout << i << endl;
break;
}
}
return 0;
}
\ No newline at end of file
1~9的数字可以组成3个3位数,设为:A,B,C, 现在要求满足如下关系:
```
B = 2 * A
C = 3 * A
```
请你写出A的所有可能答案,数字间用空格分开,数字按升序排列。
\ No newline at end of file
public class Test004 {
public static void main(String[] args) {
for (int a = 111; a <= 333; a++) {
if (hasZero(a)) {
continue;
} else {
int b = 2 * a;
int c = 3 * a;
if (hasZero(b) || hasZero(c)) {
continue;
}
String s = "" + a + b + c;
if (isFind(s)) {
System.out.print(a + " ");
}
}
}
}
private static boolean hasZero(int n) {
return String.valueOf(n).contains("0");
}
private static boolean isFind(String x) {
char[] arr = x.toCharArray();
Arrays.sort(arr);
return "123456789".equals(String.valueOf(arr));
}
}
\ No newline at end of file
1,2,3…9 这九个数字组成一个分数,其值恰好为1/3,如何组法?
\ No newline at end of file
// 九数组分数
#include <stdio.h>
void test(int x[])
{
int a = x[0] * 1000 + x[1] * 100 + x[2] * 10 + x[3];
int b = x[4] * 10000 + x[5] * 1000 + x[6] * 100 + x[7] * 10 + x[8];
if (a * 3 == b)
printf("%d / %d\n", a, b);
}
void f(int x[], int k)
{
int i, t;
if (k >= 9)
{
test(x);
return;
}
for (i = k; i < 9; i++)
{
{
t = x[k];
x[k] = x[i];
x[i] = t;
}
f(x, k + 1);
{
t = x[i];
x[i] = x[k];
x[k] = t;
}
}
}
int main()
{
int x[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
f(x, 0);
return 0;
}
\ No newline at end of file
2004年起,国际ISBN中心出版了《13位国际标准书号指南》。
原有10位书号前加978作为商品分类标识;校验规则也改变。
校验位的加权算法与10位ISBN的算法不同,具体算法是:
1. 用1分别乘ISBN的前12位中的奇数位(从左边开始数起),用3乘以偶数位,乘积之和以10为模,
2. 10与模值的差值再对10取模(即取个位的数字)即可得到校验位的值,其值范围应该为0~9。
下面的程序实现了该算法,请仔细阅读源码,填写缺失的部分。
#include <stdio.h>
// 验证成功返回 1,否则返回 0
int f(const char *s)
{
int k = 1;
int sum = 0;
int i;
for (i = 0; s[i] != '\0'; i++)
{
char c = s[i];
if (c == '-' || c == ' ')
continue;
sum += k % 2 == 1 ? (c - '0') * 3 : (c - '0');
k++;
if (k > 12)
break;
}
while (s[i] != '\0')
i++;
return (s[i - 1] - '0') == (10 - sum % 10) % 10;
}
int main()
{
printf("%d\n", f("978-7-301-04815-3"));
printf("%d\n", f("978-7-115-38821-6"));
return 0;
}
#### 问题描述
小明开了一家糖果店。他别出心裁:把水果糖包成4颗一包和7颗一包的两种。糖果不能拆包卖。
小朋友来买糖的时候,他就用这两种包装来组合。当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。
你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。大于17的任何数字都可以用4和7组合出来。
本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。
#### 输入格式
两个正整数,表示每种包装中糖的颗数(都不多于1000)
#### 输出格式
一个正整数,表示最大不能买到的糖数
#### 样例输入1
```
4 7
```
#### 样例输出1
```
17
```
#### 样例输入2
```
3 5
```
#### 样例输出2
```
7
```
\ No newline at end of file
#include <stdio.h>
bool b[100000];
int min(int a, int b)
{
if (a < b)
{
return a;
}
else
{
return b;
}
}
int main()
{
int n, m, j = 0, max = 0;
scanf("%d%d", &n, &m);
for (int i = 0; i <= m; i++)
for (int j = 0; j <= n; j++)
{
if (i * n + j * m >= 100000)
break;
b[i * n + j * m] = true;
}
for (int i = min(m, n); i <= n * m; i++)
{
if (b[i])
{
j++;
if (j == min(m, n))
{
printf("%d", max);
break;
}
}
else
{
max = i;
j = 0;
}
}
}
\ No newline at end of file
有N个瓶子,编号 1 ~ N,放在架子上。
比如有5个瓶子:
2 1 3 5 4
要求每次拿起2个瓶子,交换它们的位置。
经过若干次后,使得瓶子的序号为:
1 2 3 4 5
对于这么简单的情况,显然,至少需要交换2次就可以复位。
如果瓶子更多呢?你可以通过编程来解决。
输入格式为两行:
第一行: 一个正整数N(N<10000), 表示瓶子的数目
第二行:N个正整数,用空格分开,表示瓶子目前的排列情况。
输出数据为一行一个正整数,表示至少交换多少次,才能完成排序。
例如,输入:
```
5
3 1 2 5 4
```
程序应该输出:
```
3
```
再例如,输入:
```
5
5 4 3 2 1
```
程序应该输出:
```
2
```
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 1e4 + 10;
bool st[N];
int a[N], n, k;
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i]; //瓶子初始序号
for (int i = 1; i <= n; i++) //从每个正确序号出发
if (!st[i]) //如果没有走过
{
k++; //环数量加一
for (int j = i; !st[j]; j = a[j]) //走完这个环 每次变更指向a[j] 即瓶子初始序号的第j个
st[j] = true;
}
cout << n - k; //环最简情况为自指 则最多有n个环 当前有k个环 从K达到n则需要n-k次
return 0;
}
小明正在分析一本小说中的人物相关性。
他想知道在小说中 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 个字符。
注意:
1. Alice 和 Bob 是大小写敏感的,alice 或 bob 等并不计算在内。
2. Alice 和 Bob 应为单独的单词,前后可以有标点符号和空格,但是不能有字母。例如 Bobbi 並不算出现了 Bob。
#### 输入格式
第一行包含一个整数 K。
第二行包含一行字符串,只包含大小写字母、标点符号和空格。长度不超过 1000000。
#### 输出格式
输出一个整数,表示 Alice 和 Bob 同时出现的次数。
#### 数据范围
```
1≤K≤1000000
```
#### 输入样例:
```
20
This is a story about Alice and Bob. Alice wants to send a private message to Bob.
```
输出样例:
```
2
```
\ No newline at end of file
#include <bits/stdc++.h>
using namespace std;
int len;
string s;
bool check(int i)
{
if (len - i < 5)
return false;
return s[i + 1] == 'l' && s[i + 2] == 'i' && s[i + 3] == 'c' && s[i + 4] == 'e';
}
bool check2(int i)
{
if (len - i < 3)
return false;
return s[i + 1] == 'o' && s[i + 2] == 'b';
}
int main()
{
int k; //这里绝对不能加关闭流读入,如果这加了getline会直接读不到
cin >> k;
getchar();
getline(cin, s);
len = s.length();
vector<int> Alice, Bob;
for (int i = 0; i < len; i++)
{
if (s[i] == 'A' && check(i))
{
Alice.push_back(i);
i += 5;
}
else if (s[i] == 'B' && check2(i))
{
Bob.push_back(i);
i += 3;
}
}
int As = Alice.size(), Bs = Bob.size();
int i = 0, j = 0;
long long ans = 0;
for (int q = 0; q < As; q++)
{
while (i < Bs && Bob[i] < Alice[q] - k - 3)
i++; //左边界已经有些被排除的
while (j < Bs && Bob[j] <= Alice[q] + k + 5)
j++; //右边界
ans += j - i;
}
cout << ans << "\n";
return 0;
}
#### 题目描述
几个人一起出去吃饭是常有的事。但在结帐的时候,常常会出现一些争执。
现在有 n 个人出去吃饭,他们总共消费了 S 元。其中第 i 个人带了 ai 元。幸运的是,所有人带的钱的总数是足够付账的,但现在问题来了:每个人分别要出多少钱呢?
为了公平起见,我们希望在总付钱量恰好为 S 的前提下,最后每个人付的钱的标准差最小。这里我们约定,每个人支付的钱数可以是任意非负实数,即可以不是1分钱的整数倍。你需要输出最小的标准差是多少。
标准差的介绍:标准差是多个数与它们平均数差值的平方平均数,一般用于刻画这些数之间的“偏差有多大”。形式化地说,设第 i 个人付的钱为 bi 元,那么标准差为 :
![参见p1.png](https://img-blog.csdnimg.cn/20201015164915888.png#pic_center)
#### 输入格式
从标准输入读入数据。
第一行包含两个整数 n、S;
第二行包含 n 个非负整数 a1, …, an。
#### 输出格式
输出到标准输出。
输出最小的标准差,四舍五入保留 4 位小数。
保证正确答案在加上或减去 10^−9 后不会导致四舍五入的结果发生变化。
#### 样例1输入
```
5 2333
666 666 666 666 666
```
#### 样例输出
```
0.0000
```
#### 样例解释
每个人都出 2333/5 元,标准差为 0。
#### 样例输入
```
10 30
2 1 4 7 4 8 3 6 4 7
```
#### 样例输出
```
0.7928
```
#### 数据说明
对于 10% 的数据,所有 ai 相等;
对于 30% 的数据,所有非 0 的 ai 相等;
对于 60% 的数据,n ≤ 1000;
对于 80% 的数据,n ≤ 10^5;
对于所有数据,n ≤ 5 × 10^5, 0 ≤ ai ≤ 10^9。
#### 资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
int main()
{
int num_of_people; //人数
int total_money; //总需要付款
int each_afford[500001]; //每个人余款
cin >> num_of_people;
cin >> total_money;
for (int i = 0; i < num_of_people; i++)
{
cin >> each_afford[i];
}
sort(each_afford, each_afford + num_of_people); //将每个人余款升序排序
double avg = total_money * 1.0 / num_of_people; //计算初始平摊要给的钱
double newavg = avg; //新的平均值
double ans = 0; //方差
for (int i = 0; i < num_of_people; i++)
{
if (each_afford[i] < newavg) //有的人连AA都给不起,让他们把现有的钱全给了
{
ans = ans + pow((each_afford[i] - avg), 2); //此时的方差
total_money = total_money - each_afford[i]; //减掉给不起平摊的人的所有余款
newavg = total_money * 1.0 / (num_of_people - i - 1); //减掉给不起平摊的钱之后算的平均值
}
else
{
ans += (num_of_people - i) * pow(newavg - avg, 2);
break;
}
}
ans = sqrt(ans / num_of_people);
printf("%.4lf\n", ans);
return 0;
}
\ No newline at end of file
#### 问题描述
给定一个长度为 N 的数组$ A = [A_1; A_2; · · · A_N]$,数组中有可能有重复出现的整数。
现在小明要按以下方法将其修改为没有重复整数的数组。小明会依次修改$A_2, A_3, · · · , A_N$。
当修改 $A_i$时,小明会检查 $A_i$ 是否在$ A_1 ∼ A_{i−1} $中出现过。如果出现过,则小明会给$ A_i $加上 1 ;如果新的$ A_i $仍在之前出现过,小明会持续给$ A_i $加 1 ,直到$ A_i $没有在$ A_1 ∼ A_{i−1}$ 中出现过。
当$ A_N $也经过上述修改之后,显然 A 数组中就没有重复的整数了。
现在给定初始的 A 数组,请你计算出最终的 A 数组。
#### 输入格式
第一行包含一个整数 N。
第二行包含 N 个整数$ A_1; A_2; · · · ; A_N $。
#### 输出格式
输出 N 个整数,依次是最终的$ A_1; A_2; · · · ; A_N $。
#### 样例输入
```
5
2 1 1 3 4
```
#### 样例输出
```
2 1 3 4 5
```
#include <iostream>
using namespace std;
const int N = 1000010;
int a[N];
int find(int x)
{
if (a[x] != x)
a[x] = find(a[x]);
return a[x];
}
int main()
{
int n;
cin >> n;
for (int i = 1; i <= N; i++)
a[i] = i;
for (int i = 1; i <= n; i++)
{
int x;
cin >> x;
x = find(x);
cout << a[x] << " ";
a[x] = x + 1;
}
return 0;
}
你有一张某海域 N×N 像素的照片,”.”表示海洋、”#”表示陆地,如下所示:
```
.......
.##....
.##....
....##.
..####.
...###.
.......
```
其中”上下左右”四个方向上连在一起的一片陆地组成一座岛屿,例如上图就有 2 座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。
具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:
```
.......
.......
.......
.......
....#..
.......
.......
```
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
#### 输入格式
第一行包含一个整数N。
以下 N 行 N 列,包含一个由字符”#”和”.”构成的 N×N 字符矩阵,代表一张海域照片,”#”表示陆地,”.”表示海洋。
照片保证第 1 行、第 1 列、第 N 行、第 N 列的像素都是海洋。
#### 输出格式
一个整数表示答案。
#### 数据范围
```
1≤N≤1000
```
#### 输入样例1:
```
7
.......
.##....
.##....
....##.
..####.
...###.
.......
```
#### 输出样例1:
```
1
```
#### 输入样例2:
```
9
.........
.##.##...
.#####...
.##.##...
.........
.##.#....
.#.###...
.#..#....
.........
```
#### 输出样例2:
```
1
```
#include <iostream>
#include <queue>
using namespace std;
int n;
const int N = 1e3 + 10;
char g[N][N];
bool st[N][N]; //状态 判断是否走过
typedef pair<int, int> PII; //需要长款两个变量定位
#define x first
#define y second
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1}; //移动的偏移量
void bfs(int x, int y, int &sum, int &bound) //土地量与淹没量,后续需要使用 所以&
{
st[x][y] = true;
queue<PII> q;
q.push({x, y});
while (q.size()) //BFS必然遍历完整个岛屿
{
auto t = q.front();
q.pop();
bool is_bound = false;
sum++;
for (int i = 0; i < 4; i++)
{
int tmpx = t.x + dx[i], tmpy = t.y + dy[i];
if (tmpx < 0 || tmpx >= n || tmpy < 0 || tmpy >= n)
continue; //边界
else if (st[tmpx][tmpy])
continue; //走过
else if (g[tmpx][tmpy] == '.') //说明上一个地点临海
{
is_bound = true;
continue;
}
st[tmpx][tmpy] = true;
q.push({tmpx, tmpy});
}
if (is_bound)
bound++; //四个方向有一个临海 则该地区沉没
}
return;
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
cin >> g[i]; //读入地图
int cnt = 0; //未被完全淹没的岛屿数量
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if (g[i][j] == '#' && !st[i][j]) //当遍历到土地 且 未走过时 遍历能走到的整个岛屿
{
int sum = 0, bound = 0;
bfs(i, j, sum, bound);
if (sum == bound)
cnt++; //沉没量与土地量相等,证明该岛屿全部沉没
}
cout << cnt;
return 0;
}
如图所示六角形中,填入1~12的数字。
使得每条直线上的数字之和都相同。
图中,已经替你填好了3个数字,请你计算星号位置所代表的数字是多少?
![](https://img-blog.csdn.net/20160124154420856)
\ No newline at end of file
#include <iostream>
#include <algorithm>
using namespace std;
int n[12] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
int main()
{
do
{
int line1 = n[0] + n[2] + n[5] + n[7];
int line2 = n[0] + n[3] + n[6] + n[10];
int line3 = n[7] + n[8] + n[9] + n[10];
int line4 = n[1] + n[2] + n[3] + n[4];
int line5 = n[1] + n[5] + n[8] + n[11];
int line6 = n[4] + n[6] + n[9] + n[11];
if (line1 == line2 && line2 == line3 && line3 == line4 && line4 == line5 && line5 == line6 && n[0] == 1 && n[1] == 8 && n[11] == 3)
cout << n[5];
} while (next_permutation(n, n + 12));
return 0;
}
问题描述
![](https://img-blog.csdnimg.cn/20200526100857208.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xsX3dhbmc=,size_16,color_FFFFFF,t_70)
兰顿蚂蚁,是于1986年,由克里斯·兰顿提出来的,属于细胞自动机的一种。
平面上的正方形格子被填上黑色或白色。在其中一格正方形内有一只“蚂蚁”。
蚂蚁的头部朝向为:上下左右其中一方。
蚂蚁的移动规则十分简单:
若蚂蚁在黑格,右转90度,将该格改为白格,并向前移一格;
若蚂蚁在白格,左转90度,将该格改为黑格,并向前移一格。
规则虽然简单,蚂蚁的行为却十分复杂。刚刚开始时留下的路线都会有接近对称,像是会重复,但不论起始状态如何,蚂蚁经过漫长的混乱活动后,会开辟出一条规则的“高速公路”。
蚂蚁的路线是很难事先预测的。
你的任务是根据初始状态,用计算机模拟兰顿蚂蚁在第n步行走后所处的位置。
#### 输入格式
输入数据的第一行是 m n 两个整数(3 < m, n < 100),表示正方形格子的行数和列数。
接下来是 m 行数据。
每行数据为 n 个被空格分开的数字。0 表示白格,1 表示黑格。
接下来是一行数据:x y s k, 其中x y为整数,表示蚂蚁所在行号和列号(行号从上到下增长,列号从左到右增长,都是从0开始编号)。s 是一个大写字母,表示蚂蚁头的朝向,我们约定:上下左右分别用:UDLR表示。k 表示蚂蚁走的步数。
#### 输出格式
输出数据为两个空格分开的整数 p q, 分别表示蚂蚁在k步后,所处格子的行号和列号。
#### 样例输入
```
5 6
0 0 0 0 0 0
0 0 0 0 0 0
0 0 1 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
2 3 L 5
```
#### 样例输出
```
1 3
```
#### 样例输入
```
3 3
0 0 0
1 1 1
1 1 1
1 1 U 6
```
#### 样例输出
```
0 0
```
#include <iostream>
#include <cstdio>
using namespace std;
int a[105][105]; //定义一个二维数组存储格子颜色
int main()
{
int m, n;
int x, y, k;
char s;
cin >> m >> n;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
cin >> a[i][j];
}
}
scanf("%d %d %c %d", &x, &y, &s, &k);
while (k--)
{
if (a[x][y] == 1) //蚂蚁在黑格
{
a[x][y] = 0;
if (s == 'U')
{
y++;
s = 'R';
}
else if (s == 'D')
{
y--;
s = 'L';
}
else if (s == 'L')
{
x--;
s = 'U';
}
else if (s == 'R')
{
x++;
s = 'D';
}
}
else //蚂蚁在白格
{
a[x][y] = 1;
if (s == 'U')
{
y--;
s = 'L';
}
else if (s == 'D')
{
y++;
s = 'R';
}
else if (s == 'L')
{
x++;
s = 'D';
}
else if (s == 'R')
{
x--;
s = 'U';
}
}
}
printf("%d %d\n", x, y);
return 0;
}
{
"node_id": "569d5e11c4fc5de7844053d9a733c5e8",
"keywords": [],
"children": [],
"export": []
}
\ No newline at end of file
9名运动员参加比赛,需要分3组进行预赛。有哪些分组的方案呢?
我们标记运动员为 A,B,C,... I
下面的程序列出了所有的分组方法。
该程序的正常输出为:
```
ABC DEF GHI
ABC DEG FHI
ABC DEH FGI
ABC DEI FGH
ABC DFG EHI
ABC DFH EGI
ABC DFI EGH
ABC DGH EFI
ABC DGI EFH
ABC DHI EFG
ABC EFG DHI
ABC EFH DGI
ABC EFI DGH
ABC EGH DFI
ABC EGI DFH
ABC EHI DFG
ABC FGH DEI
ABC FGI DEH
ABC FHI DEG
ABC GHI DEF
ABD CEF GHI
ABD CEG FHI
ABD CEH FGI
ABD CEI FGH
ABD CFG EHI
ABD CFH EGI
ABD CFI EGH
ABD CGH EFI
ABD CGI EFH
ABD CHI EFG
ABD EFG CHI
..... (以下省略,总共560行)。
```
\ No newline at end of file
public class A {
public static String remain(int[] a) {
String s = "";
for (int i = 0; i < a.length; i++) {
if (a[i] == 0)
s += (char) (i + 'A');
}
return s;
}
public static void f(String s, int[] a) {
for (int i = 0; i < a.length; i++) {
if (a[i] == 1)
continue;
a[i] = 1;
for (int j = i + 1; j < a.length; j++) {
if (a[j] == 1)
continue;
a[j] = 1;
for (int k = j + 1; k < a.length; k++) {
if (a[k] == 1)
continue;
a[k] = 1;
System.out.println(
s + " " + (char) (i + 'A') + (char) (j + 'A') + (char) (k + 'A') + " " + remain(a));
a[k] = 0;
}
a[j] = 0;
}
a[i] = 0;
}
}
public static void main(String[] args) {
int[] a = new int[9];
a[0] = 1;
for (int b = 1; b < a.length; b++) {
a[b] = 1;
for (int c = b + 1; c < a.length; c++) {
a[c] = 1;
String s = "A" + (char) (b + 'A') + (char) (c + 'A');
f(s, a);
a[c] = 0;
}
a[b] = 0;
}
}
}
儿童节那天有K位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。
小明一共有N块巧克力,其中第i块是Hi x Wi的方格组成的长方形。
为了公平起见,小明需要从这 N 块巧克力中切出K块巧克力分给小朋友们。切出的巧克力需要满足:
1. 形状是正方形,边长是整数
2. 大小相同
例如一块6x5的巧克力可以切出6块2x2的巧克力或者2块3x3的巧克力。
当然小朋友们都希望得到的巧克力尽可能大,你能帮小Hi计算出最大的边长是多少么?
#### 输入
第一行包含两个整数N和K。(1 <= N, K <= 100000)
以下N行每行包含两个整数Hi和Wi。(1 <= Hi, Wi <= 100000)
输入保证每位小朋友至少能获得一块1x1的巧克力。
#### 输出
输出切出的正方形巧克力最大可能的边长。
#### 样例输入:
```
2 10
6 5
5 6
```
#### 样例输出:
```
2
```
#include <stdio.h>
#include <string.h>
int co[100100][2];
//n块巧克力,分成x*x型的。
//返回巧克力的块数
int coun(int n, int x)
{
int sum = 0;
for (int i = 0; i < n; i++)
{
sum += (co[i][0] / x) * (co[i][1] / x);
}
return sum;
}
//二分求解
int binary(int n, int k)
{
int l = 0, r = 100000;
while (l < r)
{
int mid = (r - l) / 2 + l;
if (coun(n, mid) < k)
r = mid - 1;
else if (coun(n, mid) > k)
l = mid + 1;
else
return mid;
}
return r;
}
int main()
{
int n;
int k;
scanf("%d%d", &n, &k);
for (int i = 0; i < n; i++)
scanf("%d%d", &co[i][0], &co[i][1]);
printf("%d\n", binary(n, k));
}
1/1 + 1/2 + 1/4 + 1/8 + 1/16 + … 每项是前一项的一半,如果一共有20项,求这个和是多少,结果用分数表示出来。
类似:3/2
当然,这只是加了前2项而已。分子分母要求互质。
\ No newline at end of file
#include <bits/stdc++.h>
using namespace std;
long pow_2(int b) //快速幂运算
{
long x = 2;
long res = 1;
while (b > 0)
{
if (b & 1)
res *= x;
b >>= 1; //右移一位
x = x * x;
}
return res;
}
int gcd(long a, long b) //求出最大公约数
{
if (b == 0)
return a;
return gcd(b, a % b);
}
int main()
{
cout << gcd(pow_2(20) - 1, pow_2(19)) << endl; //最大公约数
cout << pow_2(20) - 1 << "/" << pow_2(19) << endl; //输出分子分母
}
#### 问题描述
输入一个字符串,请输出这个字符串包含多少个大写字母,多少个小写字母,多少个数字。
#### 输入格式
输入一行包含一个字符串。
#### 输出格式
输出三行,每行一个整数,分别表示大写字母、小写字母和数字的个数。
#### 样例输入
```
1+a=Aab
```
#### 样例输出
```
1
3
1
```
#### 评测用例规模与约定
对于所有评测用例,字符串由可见字符组成,长度不超过 100。
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
string str;
cin >> str;
int A = 0, a = 0, number = 0;
int len = str.length();
for (int i = 0; i < len; i++)
{
if (str[i] <= '9' && str[i] >= '0')
{
number++;
}
if (str[i] <= 'Z' && str[i] >= 'A')
{
A++;
}
if (str[i] <= 'z' && str[i] >= 'a')
{
a++;
}
}
cout << A << endl;
cout << a << endl;
cout << number << endl;
return 0;
}
import java.util.Scanner;
public class CountAllKind {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String str = in.nextLine();
in.close();
int Big = 0;
int small = 0;
int digtal = 0;
for (int x = 0; x < str.length(); x++) {
if (str.charAt(x) >= 'a' && str.charAt(x) <= 'z') {
small++;
}
if (str.charAt(x) >= 'A' && str.charAt(x) <= 'Z') {
Big++;
}
if (str.charAt(x) >= '0' && str.charAt(x) <= '9') {
digtal++;
}
}
System.out.println(Big);
System.out.println(small);
System.out.println(digtal);
}
}
#### 问题描述
有n个小朋友围坐成一圈。老师给每个小朋友随机发偶数个糖果,然后进行下面的游戏:
每个小朋友都把自己的糖果分一半给左手边的孩子。
一轮分糖后,拥有奇数颗糖的孩子由老师补给1个糖果,从而变成偶数。
反复进行这个游戏,直到所有小朋友的糖果数都相同为止。
你的任务是预测在已知的初始糖果情形下,老师一共需要补发多少个糖果。
#### 输入格式
程序首先读入一个整数N(2<N<100),表示小朋友的人数。
接着是一行用空格分开的N个偶数(每个偶数不大于1000,不小于2)
#### 输出格式
要求程序输出一个整数,表示老师需要补发的糖果数。
#### 样例输入
```
3
2 2 4
```
#### 样例输出
```
4
```
\ No newline at end of file
#include <iostream>
using namespace std;
int main()
{
int n; //小朋友数量
cin >> n;
int *Candy = new int[n]; //存储每个小朋友的糖果数
for (int i = 0; i < n; i++)
{
cin >> Candy[i];
}
int total = 0; //补发的糖果总数
while (1)
{
bool flag = true; //判断每人糖果数量是否相同
for (int i = 1; i < n; i++)
{
if (Candy[0] != Candy[i])
{ //不相同
flag = false;
break;
}
}
if (flag == true) //数量相同,退出循环
break;
int temp = Candy[n - 1]; //记录最后一个小朋友手中的糖果
for (int i = n - 1; i >= 0; i--)
{
if (i == 0)
{ //如果是第一个小朋友
Candy[0] = Candy[0] / 2 + temp / 2; //最后一个小朋友获得最初第一个人的一半
}
else
Candy[i] = Candy[i] / 2 + Candy[i - 1] / 2; // 每个小朋友都把自己的糖果分一半给左手边的孩子
if (Candy[i] % 2 != 0)
{ //如果此时手中为奇数,则补糖果
Candy[i] += 1;
total += 1; //补发数量加1
}
}
}
cout << total << endl;
}
某市市长获得了若干批口罩,给定每批口罩的数量,市长要把口罩分配给市内的2所医院。
```
masks = [9090400, 8499400, 5926800, 8547000, 4958200, 4422600, 5751200, 4175600, 6309600, 5865200, 6604400, 4635000, 10663400, 8087200, 4554000]
```
由于物流限制,每一批口罩只能全部分配给其中一家医院。
市长希望2所医院获得的口罩总数之差越小越好。
请你计算这个差最小是多少?
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
long int masks[15] = {9090400, 8499400, 5926800, 8547000, 4958200,
4422600, 5751200, 4175600, 6309600,
5865200, 6604400, 4635000, 10663400, 8087200, 4554000};
long ans = 1000000000;
void dfs(int n, long h1, long h2)
{
if (n == 15)
{
ans = min(ans, abs(h1 - h2));
return;
}
dfs(n + 1, h1 + masks[n], h2);
dfs(n + 1, h1, h2 + masks[n]);
}
int main()
{
dfs(0, 0, 0);
cout << ans;
}
一根高筋拉面,中间切一刀,可以得到2根面条。
如果先对折1次,中间切一刀,可以得到3根面条。
如果连续对折2次,中间切一刀,可以得到5根面条。
那么,连续对折10次,中间切一刀,会得到多少面条呢?
\ No newline at end of file
#include <iostream>
using namespace std;
int main()
{
int f[10];
f[1] = 3;
for (int i = 2; i < 11; i++)
f[i] = f[i - 1] * 2 - 1; //等同(f[i-1]-1)*2+1
cout << f[10];
}
如下的代码判断 needle_start指向的串是否为haystack_start指向的串的前缀,如不是,则返回NULL。
比如:"abcd1234" 就包含了 "abc" 为前缀
\ No newline at end of file
#include <bits/stdc++.h>
using namespace std;
char *prefix(char *haystack_start, char *needle_start)
{
char *haystack = haystack_start;
char *needle = needle_start;
while (*haystack && *needle)
{ //这两个指针都没有越界
//if() return NULL; //填空位置
//要移动指针,并判断,if()
if ((*haystack++) != *(needle++))
return NULL;
}
if (*needle)
return NULL; //needle没有越界,返回NULL
return haystack_start;
}
int main()
{
cout << prefix("abcd123", "abd") << endl;
return 0;
}
#### 问题描述
如下图所示,3 x 3 的格子中填写了一些整数。
```
+--*--+--+
|10* 1|52|
+--****--+
|20|30* 1|
*******--+
| 1| 2| 3|
+--+--+--+
```
我们沿着图中的星号线剪开,得到两个部分,每个部分的数字和都是60。
本题的要求就是请你编程判定:对给定的m x n 的格子中的整数,是否可以分割为两个部分,使得这两个区域的数字和相等。
如果存在多种解答,请输出包含左上角格子的那个区域包含的格子的最小数目。
如果无法分割,则输出 0。
#### 输入格式
程序先读入两个整数 m n 用空格分割 (m,n<10)。
表示表格的宽度和高度。
接下来是n行,每行m个正整数,用空格分开。每个整数不大于10000。
#### 输出格式
输出一个整数,表示在所有解中,包含左上角的分割区可能包含的最小的格子数目。
#### 样例输入1
```
3 3
10 1 52
20 30 1
1 2 3
```
#### 样例输出1
```
3
```
#### 样例输入2
```
4 3
1 1 1 1
1 30 80 2
1 1 1 100
```
#### 样例输出2
```
10
```
\ No newline at end of file
#include <stdio.h>
int m, n, half = 0, sum = 0, minValue = 100, count = 0, select = 0, tnum;
int num[10][10] = {0}, flag[10][10] = {0};
int xzb[] = {-1, 1, 0, 0}; /*上下左右*/
int yzb[] = {0, 0, -1, 1};
int isok(int x, int y) /*判断传入的坐标值是否能被选入*/
{
int yes = 0; /*不越界并且不超出和一半*/
if ((x >= n || x < 0) || (y >= m || y < 0) || (flag[x][y] == 1) || (sum + num[x][y] > half))
yes = 1; /*冲突*/
return yes;
}
void back(int value, int x, int y) /*执行回退处理*/
{
if (x == 0 && y == 0) /*如果将num[0][0]回溯掉,则标记为未选入*/
select = 0;
--count;
sum -= value;
flag[x][y] = 0;
}
void dfs(int value, int x, int y) /*dfs搜索*/
{
int i, t1, t2;
if (x == 0 && y == 0) /*主要用于B点开始的搜素,判断num[0][0]有没有被选入*/
select = 1;
flag[x][y] = 1; /*标记为已走过*/
++count; /*已走过点的个数*/
sum += value; /*已走过的点的和*/
if (sum == half)
{
if (select == 1) /*如果num[0,0]被选入,主要用于非[0,0]点开始的搜索*/
tnum = count;
else
tnum = n * m - count;
minValue = minValue > tnum ? tnum : minValue; /*选出剪掉点数最少的方案*/
}
else
{
for (i = 0; i < 4; ++i) /*按 上下左右 顺序遍历*/
{
t1 = x + xzb[i]; /*引入t1,t2目的是使传入的x,y值不变,便于下面的回退*/
t2 = y + yzb[i];
if (isok(t1, t2) == 1) /*是否可走*/
continue;
dfs(num[t1][t2], t1, t2);
}
}
back(value, x, y); /*如果上下左右都不可走:回退*/
}
int main()
{
int i, j, maxNum = 0, all = 0;
scanf("%d%d", &m, &n);
for (i = 0; i < n; ++i)
for (j = 0; j < m; ++j)
{
scanf("%d", &num[i][j]);
all += num[i][j]; /*all为总和*/
if (num[i][j] > maxNum) /*找出最大值*/
maxNum = num[i][j];
}
if (all % 2 != 0 || maxNum > all / 2) /*如果和为基数或者最大值大于总和一半*/
printf("0\n");
else
{
half = all / 2;
/*将格子每个点都作为起点搜索一遍,两个for循环*/
for (i = 0; i < n; ++i)
for (j = 0; j < m; ++j)
{
select = 0;
dfs(num[i][j], i, j);
}
if (minValue != 100) /*找不到*/
printf("%d\n", minValue);
else
printf("0\n");
}
return 0;
}
\ No newline at end of file
如图
![](https://img-blog.csdnimg.cn/20190313183756434.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1N5bHZpYV9XdTUx,size_16,color_FFFFFF,t_70)
有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)比如
![](https://img-blog.csdnimg.cn/20190313183806622.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1N5bHZpYV9XdTUx,size_16,color_FFFFFF,t_70)
![](https://img-blog.csdnimg.cn/2019031318382071.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1N5bHZpYV9XdTUx,size_16,color_FFFFFF,t_70)中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
\ No newline at end of file
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int row = 3, col = 4;
int a[] = {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1};
int map[row][col];
bool st[row][col];
int ans;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
//连通 直接走完连通的部分
void dfs(int x, int y)
{
st[x][y] = true;
for (int i = 0; i < 4; i++)
{
int tx = x + dx[i], ty = y + dy[i];
if (tx < 0 || tx >= row || ty < 0 || ty >= col)
continue;
if (st[tx][ty] || !map[tx][ty])
continue;
dfs(tx, ty);
}
}
int main()
{
do
{
//重置
memset(map, 0, sizeof map), memset(st, false, sizeof st);
int num = 0, cnt = 0;
//读入
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++)
map[i][j] = a[cnt++];
//连通
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++)
if (!st[i][j] && map[i][j])
num++, dfs(i, j);
//检查 连通块只有一个,正确
if (num == 1)
ans++;
} while (next_permutation(a, a + 12));
cout << ans;
return 0;
}
#### 题目描述:
我们都知道:1+2+3+ … + 49 = 1225
现在要求你把其中两个不相邻的加号变成乘号,使得结果为2015
比如:
1+2+3+…+1011+12+…+2728+29+…+49 = 2015 就是符合要求的答案。
请你寻找另外一个可能的答案,并把位置靠前的那个乘号左边的数字提交(对于示例,就是提交10)。
#include <iostream>
using namespace std;
int main()
{ //i是左侧X号前一个数,j是右侧X号前一个数
for (int i = 1; i <= 46; i++) //i,j这里都确定的X的前一个值,则最末X前一个值为48,因为中间必须预留+,所以保留两个X的最末则为46
for (int j = i + 2; j <= 48; j++) //因为中间必须预留+,所以每次+2,最末X前一个值为48
if (i * (i + 1) + j * (j + 1) - (i + i + 1) - (j + j + 1) == 2015 - 1225)
if (i != 10)
cout << i << endl; //题目要求判断除了10以外的可能
return 0;
}
#### 问题描述
小蓝正在学习一门神奇的语言,这门语言中的单词都是由小写英文字母组成,有些单词很长,远远超过正常英文单词的长度。小蓝学了很长时间也记不住一些单词,他准备不再完全记忆这些单词,而是根据单词中哪个字母出现得最多来分辨单词。
现在,请你帮助小蓝,给了一个单词后,帮助他找到出现最多的字母和这个字母出现的次数。
#### 输入格式
输入一行包含一个单词,单词只由小写英文字母组成。
#### 输出格式
输出两行,第一行包含一个英文字母,表示单词中出现得最多的字母是哪
个。如果有多个字母出现的次数相等,输出字典序最小的那个。
第二行包含一个整数,表示出现得最多的那个字母在单词中出现的次数。
#### 样例输入
```
lanqiao
```
#### 样例输出
```
a 2
```
#### 样例输入
```
longlonglongistoolong
```
#### 样例输出
```
o 6
```
#### 评测用例规模与约定
对于所有的评测用例,输入的单词长度不超过 1000。
#include "stdio.h"
#include "string.h"
int main()
{
//定义简单的哈希表并确定表长为128(因为ASCII码只占一个字节8位)并赋初值为0
int a[128] = {0};
char s[1000];
scanf("%s", s);
int len = strlen(s);
//max用于更新最大次数,t用于更新对应的字符
int max = 0;
char t = 0;
//完成哈希表的建立(即遍历一遍字符串得到值键对)
for (int i = 0; i < len; i++)
{
a[s[i]]++;
if (max < a[s[i]])
{ //完成最大次数的扫描,以及该情况下对应键的记录
max = a[s[i]];
t = s[i];
} //若出现相同次数利用ASCII码来进行判断,小的记录下来
else if (max == a[s[i]])
{
if (t > s[i])
{
t = s[i];
}
}
} //最后进行字符以及对应次数的输出即可。
printf("%c\n%d", t, max);
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
int max = 0;
int index = 0;
String a = "abcdefghijklmnopqrstuvwxyz";
int b[] = new int[26];
for (int i = 0; i < s.length(); i++) {
b[a.indexOf(s.charAt(i))]++;
}
for (int j = 0; j < b.length; j++) {
if (b[j] > max) {
max = b[j];
index = j;
}
}
System.out.println(a.substring(index, index + 1));
System.out.println(max);
}
}
#### 问题描述
小明最近在研究压缩算法。
他知道,压缩的时候如果能够使得数值很小,就能通过熵编码得到较高的压缩比。
然而,要使数值很小是一个挑战。
最近,小明需要压缩一些正整数的序列,这些序列的特点是,后面出现的数字很大可能是刚出现过不久的数字。对于这种特殊的序列,小明准备对序列做一个变换来减小数字的值。
变换的过程如下:
从左到右枚举序列,每枚举到一个数字,如果这个数字没有出现过,刚将数字变换成它的相反数,如果数字出现过,则看它在原序列中最后的一次出现后面(且在当前数前面)出现了几种数字,用这个种类数替换原来的数字。
比如,序列(a1, a2, a3, a4, a5)=(1, 2, 2, 1, 2)在变换过程为:
a1: 1未出现过,所以a1变为-1;
a2: 2未出现过,所以a2变为-2;
a3: 2出现过,最后一次为原序列的a2,在a2后、a3前有0种数字,所以a3变为0;
a4: 1出现过,最后一次为原序列的a1,在a1后、a4前有1种数字,所以a4变为1;
a5: 2出现过,最后一次为原序列的a3,在a3后、a5前有1种数字,所以a5变为1。
现在,给出原序列,请问,按这种变换规则变换后的序列是什么。
#### 输入
输入第一行包含一个整数n,表示序列的长度。
第二行包含n个正整数,表示输入序列。
#### 输出
输出一行,包含n个数,表示变换后的序列。
#### 输入例子 1
```
5
1 2 2 1 2
```
#### 输出例子 1
```
-1 -2 0 1 1
```
#### 输入例子 2
```
12
```
#### 输出例子 2
```
-1 0 -2 -3 1 1 2 2 0 0 2 2
```
\ No newline at end of file
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 5;
int a[maxn], tree[maxn << 2]; // 假设层数 M = log 2 (n - 1), 树节点数就要开2倍了
// 循环中遍历最后一个结点的的子节点(虽然不存在) 需要 2n * 2的数组大小
int n, maxpoint;
void init()
{
maxpoint = 1;
while (maxpoint < n)
maxpoint <<= 1; //比最后一个结点大的2的倍数个结点
memset(tree, 0, sizeof(tree));
memset(a, 0, sizeof(a));
}
void update(int k, int addnum)
{ // addnum 在出现前边时更新所有子节点 + 1, 出现后边时 所有子节点都 - 1
k += maxpoint - 1; // 每个节点都当作根节点一样遍历子节点
tree[k] += addnum;
while (k)
{
k = (k - 1) >> 1; // 访问父节点直到根结点
tree[k] += addnum;
}
}
int query(int a, int b, int k, int l, int r)
{
if (a == b || (r <= a || l >= b))
return 0; // 不符合查询条件 返回 0
if (a <= l && r <= b)
return tree[k]; // 子区域就直接返回
else
{
int mid = (l + r) >> 1;
return query(a, b, (k << 1) + 1, l, mid) + query(a, b, (k + 1) << 1, mid, r);
}
}
int main()
{
int temp;
map<int, int> mp;
cin >> n;
init();
for (int i = 0; i < n; i++)
{
cin >> temp;
if (mp.count(temp))
{
int pre = mp[temp];
a[i] = query(pre + 1, i, 0, 0, maxpoint);
update(pre, -1);
}
else
{
a[i] = -temp;
}
mp[temp] = i;
update(i, 1);
}
for (int i = 0; i < n; i++)
cout << a[i] << " ";
return 0;
}
求1个整数的第k位数字有很多种方法。
以下的方法就是一种。
#include <stdio.h>
int len(int x)
{
if (x < 10)
return 1;
return len(x / 10) + 1;
}
// 取x的第k位数字
int f(int x, int k)
{
if (len(x) - k == 0)
return x % 10;
return f(x / 10, k); //填空
}
int main()
{
int x = 23574;
printf("%d\n", f(x, 3));
return 0;
}
\ No newline at end of file
#### 问题描述
两个人玩取球的游戏。
一共有N个球,每人轮流取球,每次可取集合{n1,n2,n3}中的任何一个数目。
如果无法继续取球,则游戏结束。此时,持有奇数个球的一方获胜。如果两人都是奇数,则为平局。
假设双方都采用最聪明的取法,第一个取球的人一定能赢吗?
试编程解决这个问题。
#### 输入
第一行3个正整数n1 n2 n3,空格分开,表示每次可取的数目 (0<n1,n2,n3<100)
第二行5个正整数x1 x2 … x5,空格分开,表示5局的初始球数(0<xi<1000)
#### 输出
一行5个字符,空格分开。分别表示每局先取球的人能否获胜。
能获胜则输出+,
次之,如有办法逼平对手,输出0,
无论如何都会输,则输出 -
#### 输入例子 1
```
1 2 3
1 2 3 4 5
```
#### 输出例子 1
```
+ 0 + 0 -
```
#### 输入例子 2
```
1 4 5
10 11 12 13 15
```
#### 输出例子 2
```
0 - 0 + +
```
#### 输入例子 3
```
2 3 5
7 8 9 10 11
```
#### 输出例子 3
```
+ 0 0 0 0
```
\ No newline at end of file
#include <bits/stdc++.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int SIZE = 1e3 + 5;
int dp[SIZE][2][2];
int a[3];
int dfs(int now, int nowplayer, int otherplayer)
{
if (dp[now][nowplayer][otherplayer])
{
return dp[now][nowplayer][otherplayer];
}
if (now < a[0])
{
if ((nowplayer & 1) == (otherplayer & 1))
return -1; //平
if (nowplayer & 1)
return 1; //胜
return 2; //负
}
else
{
bool noplayerwin = false;
for (int i = 2; i >= 0; i--)
{
if (a[i] > now)
continue;
else
{
int otherresult = dfs(now - a[i], otherplayer, (nowplayer + a[i]) & 1);
if (otherresult == 2)
return dp[now][nowplayer][otherplayer] = 1;
if (otherresult == -1)
noplayerwin = true;
}
}
if (noplayerwin)
return dp[now][nowplayer][otherplayer] = -1;
return dp[now][nowplayer][otherplayer] = 2;
}
}
int main()
{
int maxnum;
memset(dp, 0, sizeof(dp));
cin >> a[0] >> a[1] >> a[2];
sort(a, a + 3);
for (int i = 1; i <= 5; i++)
{
cin >> maxnum;
switch (dfs(maxnum, 0, 0))
{
case 1:
cout << "+ ";
break;
case 2:
cout << "- ";
break;
case -1:
cout << "0 ";
break;
}
}
return 0;
}
今盒子里有n个小球,A、B两人轮流从盒中取球,每个人都可以看到另一个人取了多少个,也可以看到盒中还剩下多少个,并且两人都很聪明,不会做出错误的判断。
我们约定:
每个人从盒子中取出的球的数目必须是:1,3,7或者8个。轮到某一方取球时不能弃权!
A先取球,然后双方交替取球,直到取完。
被迫拿到最后一个球的一方为负方(输方)
请编程确定出在双方都不判断失误的情况下,对于特定的初始球数,A是否能赢?
程序运行时,从标准输入获得数据,其格式如下:
先是一个整数n(n<100),表示接下来有n个整数。然后是n个整数,每个占一行(整数<10000),表示初始球数。
程序则输出n行,表示A的输赢情况(输为0,赢为1)。
例如,用户输入:
```
4
1
2
10
18
```
则程序应该输出:
```
0
1
1
0
```
\ No newline at end of file
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int vis[20000];
int ff(int x)
{
if (x > 8)
return vis[x - 8] && vis[x - 7] && vis[x - 3] && vis[x - 1];
else if (x > 7)
return vis[x - 7] && vis[x - 3] && vis[x - 1];
else if (x > 3)
return vis[x - 1] && vis[x - 3];
else if (x > 1)
return vis[x - 1];
else
return 1;
}
int main()
{
int l, n, m, i, j;
memset(vis, 0, sizeof(vis));
vis[2] = 1;
vis[4] = 1;
for (i = 5; i < 10010; i++)
{
if (i > 8)
vis[i] = ff(i - 1) || ff(i - 3) || ff(i - 7) || ff(i - 8);
else if (i > 7)
vis[i] = ff(i - 1) || ff(i - 3) || ff(i - 7);
else if (i > 3)
vis[i] = ff(i - 1) || ff(i - 3);
else if (i > 1)
vis[i] = ff(i - 1);
}
scanf("%d", &l);
while (l--)
{
scanf("%d", &n);
printf("%d\n", vis[n]);
}
return 0;
}
\ No newline at end of file
福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式:
ABCDE * ? = EDCBA
他对华生说:“ABCDE应该代表不同的数字,问号也代表某个数字!”
华生:“我猜也是!”
于是,两人沉默了好久,还是没有算出合适的结果来。
请你利用计算机的优势,找到破解的答案。
把 ABCDE 所代表的数字写出来。
#include <iostream>
using namespace std;
bool isOk(int n, int *v)
{
int s[10] = {0};
for (int i = 0; i < 5; i++)
{
if (s[v[i]]) //如果该数重复出现了,就可以直接返回false
return false;
s[v[i]] = 1; // 已出现过的数做标记
}
return true;
}
int getNum(int *v)
{
int s = 0;
for (int i = 0; i < 5; i++)
s = s * 10 + v[i]; //逆序组合该数
return s;
}
int main()
{
int i, j, a, b, v[5] = {0};
for (i = 12345; i <= 98765; i++)
{
for (a = 0, b = 1; a <= 5; a++, b *= 10)
v[a] = i / b % 10;
if (isOk(i, v))
for (int j = 2; j < 9; j++)
if (i * j == getNum(v))
cout << i;
}
return 0;
}
\ No newline at end of file
史丰收速算法的革命性贡献是:从高位算起,预测进位。不需要九九表,彻底颠覆了传统手算!
速算的核心基础是:1位数乘以多位数的乘法。
其中,乘以7是最复杂的,就以它为例。
因为,1/7 是个循环小数:0.142857...,如果多位数超过 142857...,就要进1
同理,2/7, 3/7, ... 6/7 也都是类似的循环小数,多位数超过 n/7,就要进n
下面的程序模拟了史丰收速算法中乘以7的运算过程。
乘以 7 的个位规律是:偶数乘以2,奇数乘以2再加5,都只取个位。
乘以 7 的进位规律是:
```
满 142857... 进1,
满 285714... 进2,
满 428571... 进3,
满 571428... 进4,
满 714285... 进5,
满 857142... 进6
```
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
//计算个位
int ge_wei(int a)
{
if (a % 2 == 0)
return (a * 2) % 10;
else
return (a * 2 + 5) % 10;
}
//计算进位
int jin_wei(char *p)
{
char *level[] =
{
"142857",
"285714",
"428571",
"571428",
"714285",
"857142"};
char buf[7];
buf[6] = '\0';
strncpy(buf, p, 6); //头文件<string.h>
int i;
for (i = 5; i >= 0; i--)
{
int r = strcmp(level[i], buf);
if (r < 0)
return i + 1;
while (r == 0)
{
p += 6;
strncpy(buf, p, 6);
r = strcmp(level[i], buf);
if (r < 0)
return i + 1;
if (r > 0)
return i; /**填空,填空位置与上一语句相似。在此若填写else return i;,输出结果相同*/
}
}
return 0;
}
//多位数乘以7
void f(char *s)
{
int head = jin_wei(s);
if (head > 0)
printf("%d", head);
char *p = s;
while (*p)
{
int a = (*p - '0');
int x = (ge_wei(a) + jin_wei(p + 1)) % 10;
printf("%d", x);
p++;
}
printf("\n");
}
int main()
{
f("428571428571");
f("34553834937543");
return 0;
}
\ No newline at end of file
新冠疫情由新冠病毒引起,最近在 A 国蔓延,为了尽快控制疫情,A 国准 备给大量民众进病毒核酸检测。
然而,用于检测的试剂盒紧缺。为了解决这一困难,科学家想了一个办法:合并检测。即将从多个人(k 个)采集的标本放到同一个试剂盒中进行检测。如果结果为阴性,则说明这 k 个人都是阴性,用一个试剂盒完成了 k 个人的检测。如果结果为阳性,则说明 至少有一个人为阳性,需要将这 k 个人的样本全部重新独立检测(从理论上看, 如果检测前 k−1 个人都是阴性可以推断出第 k 个人是阳性,但是在实际操作中 不会利用此推断,而是将 k 个人独立检测),加上最开始的合并检测,一共使用 了 k + 1 个试剂盒完成了 k 个人的检测。
A 国估计被测的民众的感染率大概是 1%,呈均匀分布。请问 k 取多少能最节省试剂盒?
#include <bits/stdc++.h>
using namespace std;
int main()
{
int N = 1000;
int ans;
int minn = 9999999;
int sum = 0; //试剂盒的数量
for (int k = 1; k <= 1000; k++)
{
if (N % k == 0)
{
sum = N / k + 10 * k;
}
else
{
sum = N / k + 10 * k + 1;
}
if (sum < minn)
{
minn = sum;
ans = k;
}
}
cout << ans;
return 0;
}
#### 问题描述
给定 N 个加号、M 个减号以及 N + M + 1 个整数 A1,A2,··· ,AN+M+1,小明想知道在所有由这 N 个加号、M 个减号以及 N + M +1 个整数凑出的合法的 后缀表达式中,结果最大的是哪一个?
请你输出这个最大的结果。 例如使用1 2 3 + -,则 “2 3 + 1 -” 这个后缀表达式结果是 4,是最大的。
#### 输入格式
第一行包含两个整数 N 和 M。 第二行包含 N + M + 1 个整数 A1,A2,··· ,AN+M+1。
#### 输出格式
输出一个整数,代表答案。
#### 样例输入
```
1 1
1 2 3
```
#### 样例输出
```
4
```
#### 评测用例规模与约定
对于所有评测用例,0≤ N,M ≤100000,−10^9 ≤ Ai ≤10^9。
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
ll a[200010];
int main()
{
int n, m, sum;
cin >> n >> m;
sum = n + m + 1;
int neg = 0; //负数个数
for (int i = 1; i <= sum; i++)
{
cin >> a[i];
if (a[i] < 0)
neg++;
}
sort(a + 1, a + 1 + sum);
ll ans = 0;
if (m == 0)
{ //若没有负号
for (int i = 1; i <= sum; i++)
ans += a[i];
}
else
{
if (neg == 0)
{ //若没有负数
ans -= a[1];
for (int i = 2; i <= sum; i++)
ans += abs(a[i]);
}
else
{
if (neg == sum)
{ //若全为负数
for (int i = 1; i < sum; i++)
ans += abs(a[i]);
ans += a[sum];
}
else
{
for (int i = 1; i <= sum; i++)
ans += abs(a[i]);
}
}
}
cout << ans;
return 0;
}
小明被不明势力劫持,后莫名其妙被扔到x星站再无问津。
小明得知每天都有飞船飞往地球,但需要 108 元的船票,而他却身无分文,他决定在 x 星战打工。
好心的老板答应包食宿,第 1 天给他 1 元钱,并且,以后的每一天都比前一天多2元钱,直到他有足够的钱买票。
请计算一下,小明在第几天就能凑够 108 元,返回地球。
#include <iostream>
using namespace std;
int main()
{
int money = 0, day = 0;
for (int i = 1;; i += 2)
{
day++;
money += i;
if (money >= 108)
{
cout << day << endl;
break;
}
}
return 0;
}
啤酒每罐2.3元,饮料每罐1.9元。小明买了若干啤酒和饮料,一共花了82.3元。
我们还知道他买的啤酒比饮料的数量少,请你计算他买了几罐啤酒。
\ No newline at end of file
#include <iostream>
using namespace std;
int main(void)
{
int x, y;
for (x = 0; x <= 19; x++)
{
for (y = 43; y > x; y--)
{
if (2.3 * x + 1.9 * y == 82.3)
{
cout << x << endl;
}
}
}
return 0;
}
\ No newline at end of file
四平方和定理,又称为拉格朗日定理:
每个正整数都可以表示为至多4个正整数的平方和。
如果把0包括进去,就正好可以表示为4个数的平方和。
比如:
```
5 = 0^ 2 + 0^ 2 + 1^ 2 + 2^2
7 = 1^ 2 + 1^ 2 + 1^ 2 + 2^2
(^符号表示乘方的意思)
```
对于一个给定的正整数,可能存在多种平方和的表示法。
要求你对4个数排序:
```
0 <= a <= b <= c <= d
```
并对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法
程序输入为一个正整数N (N<5000000)
要求输出4个非负整数,按从小到大排序,中间用空格分开
例如,输入:
```
5
```
则程序应该输出:
```
0 0 1 2
```
再例如,输入:
```
12
```
则程序应该输出:
```
0 2 2 2
```
再例如,输入:
```
773535
```
则程序应该输出:
```
1 1 267 838
```
\ No newline at end of file
#include <iostream>
#include <cstdio>
#include <map>
#include <cmath>
using namespace std;
int N;
map<int, int> cache; //int和int映射,哈希表用于缓存数值
int main()
{
scanf("%d", &N);
for (int c = 0; c * c <= N / 2; c++)
{
for (int d = c; c * c + d * d <= N; d++)
{
if (cache.find(c * c + d * d) == cache.end()) //如果未找到,再去存,已经存在就不需要去存了
cache[c * c + d * d] = c; //查平方数,先要看cache里面有没有,没有说明它不是一个平方数存起来
//有的话通过较小的数映射找到它
}
}
//c*c+d*d要比a*a+d*d要大(至少相同)
for (int a = 0; a * a <= N / 4; a++)
{ //单独看a*a小于等于N/4
for (int b = a; a * a + b * b <= N / 2; b++)
{ //a*a+b*b小于等于N/2
if (cache.find(N - a * a - b * b) != cache.end())
{ //查表,能找到
int c = cache[N - a * a - b * b]; //c就可以知道
int d = int(sqrt(N - a * a - b * b - c * c)); //d开方
printf("%d %d %d %d\n", a, b, c, d);
return 0; //跳出整个主函数
}
}
}
return 0;
}
//整个过程不需要再排序,因为一开始在写代码时,就已经限定了顺序大小,c*c+d*d要比a*a+d*d要大
#### 问题描述
2020 年春节期间,有一个特殊的日期引起了大家的注意:2020年2月2日。因为如果将这个日期按“yyyymmdd” 的格式写成一个8 位数是20200202,恰好是一个回文数。我们称这样的日期是回文日期。
有人表示20200202 是“千年一遇” 的特殊日子。对此小明很不认同,因为不到2年之后就是下一个回文日期:20211202 即2021年12月2日。
也有人表示20200202 并不仅仅是一个回文日期,还是一个ABABBABA型的回文日期。对此小明也不认同,因为大约100 年后就能遇到下一个ABABBABA 型的回文日期:21211212 即2121 年12 月12 日。算不上“千年一遇”,顶多算“千年两遇”。
给定一个8 位数的日期,请你计算该日期之后下一个回文日期和下一个ABABBABA型的回文日期各是哪一天。
#### 输入格式
输入包含一个八位整数N,表示日期。
#### 输出格式
输出两行,每行1 个八位数。第一行表示下一个回文日期,第二行表示下
一个ABABBABA 型的回文日期。
#### 样例输入
```
20200202
```
#### 样例输出
```
20211202
21211212
```
#### 评测用例规模与约定
对于所有评测用例,10000101 ≤ N ≤ 89991231,保证N 是一个合法日期的8位数表示。
\ No newline at end of file
#include <iostream>
#include <algorithm>
using namespace std;
int days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool check(int year)
{
return year % 400 == 0 || year % 4 == 0 && year % 100 != 0;
}
int get_day(int year, int month)
{
if (month == 2)
return 28 + check(year);
return days[month];
}
int main()
{
int n;
cin >> n;
string ans1, ans2;
bool flag1 = false, flag2 = false;
for (int i = n / 10000; i <= 9999; i++)
{
string a = to_string(i);
string b = a;
reverse(b.begin(), b.end());
if (a + b <= to_string(n))
continue;
int month = stoi(b.substr(0, 2));
int day = stoi(b.substr(2, 2));
if (month < 1 || month > 12)
continue;
if (day < 1 || day > get_day(i, month))
continue;
string s1 = a.substr(0, 2);
string s2 = a.substr(2, 2);
if (!flag1)
ans1 = a + b, flag1 = true;
if (!flag2 && s1 == s2 && s1[0] != s1[1])
ans2 = a + b, flag2 = true;
if (flag1 && flag2)
break;
}
cout << ans1 << endl;
cout << ans2 << endl;
return 0;
}
数学发展历史上,圆周率的计算曾有许多有趣甚至是传奇的故事。其中许多方法都涉及无穷级数。
图中所示,就是一种用连分数的形式表示的圆周率求法。
![](https://img-blog.csdnimg.cn/20210128181357213.png)
下面的程序实现了该求解方法。实际上数列的收敛对x的初始值 并不敏感。
结果打印出圆周率近似值(保留小数点后4位,并不一定与圆周率真值吻合)。
\ No newline at end of file
package java_2014_B;
public class Main005_圆周率 {
public static void main(String[] args) {
double x = 111;
for (int n = 10000; n >= 0; n--) {
int i = 2 * n + 1;
x = 2 + (i * i / x);
}
System.out.println(String.format("%.4f", 4 / (x - 1)));
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册