最短路径应该是往右走圆的半径长度 r = 23 3 2 + 66 6 2 r = \sqrt{233^2 + 666^2} r=2332+6662 ,然后再延着圆弧走到 ( 233 , 666 ) (233, 666) (233,666) 这个点。圆弧长度: l = α r = arctan 666 233 r l = \alpha r = \arctan{\frac{666}{233}}r l=αr=arctan233666r ( α \alpha α 是圆弧对应的圆心角,以弧度制表示)。答案是 1576 1576 1576
代码
cpp复制代码
#include <bits/stdc++.h>
using namespace std;
int main() {
double r = sqrt(233 * 233 + 666 * 666);
double ang = atan(1.0 * 666 / 233);
cout << (int)round(ang * r + r) << endl;
return 0;
}
B. 客流量上限
本题总分:5 分
问题描述
一家连锁旅馆在全国拥有 2025 2025 2025 个分店,分别编号为 1 1 1 至 2025 2025 2025。随着节日临近,总部决定为每家分店设定每日客流量的上限,分别记作 A 1 A_1 A1, A 2 A2 A2, ... \ldots ..., A 2025 A_{2025} A2025。这些上限并非随意分配,而是需要满足以下约束条件:
A 1 A_1 A1, A 2 A2 A2, ... \ldots ..., A 2025 A_{2025} A2025 必须是 1 1 1 至 2025 2025 2025 的一个排列,即每个 A i A_i Ai 均是 1 1 1 至 2025 2025 2025 之间的整数,且所有 Ai 互不相同。
对于任意分店 i i i 和 j j j( 1 ≤ i , j ≤ 2025 1 ≤ i, j ≤ 2025 1≤i,j≤2025, i i i 可等于 j j j),它们的客流量上限 A i A_i Ai 和 A j A_j Aj 的乘积不得超过 i × j + 2025 i \times j + 2025 i×j+2025。这些约束旨在平衡各分店客流压力,确保服务质量和运营稳定性。现在,请你计算这样的分配方案究竟有多少种。由于答案可能很大,你只\需输出其对 1 0 9 + 7 10^9 + 7 109+7 取余后的结果即可。
对于 30 % 30\% 30% 的评测用例, 1 ≤ N ≤ 100 1 \le N \le 100 1≤N≤100, 1 ≤ A i ≤ 100 1 \le A_i \le 100 1≤Ai≤100。
对于 100 % 100\% 100% 的评测用例, 1 ≤ N ≤ 1 0 5 1 \le N \le 10^5 1≤N≤105, 1 ≤ A i ≤ 1 0 9 1 \le A_i \le 10^9 1≤Ai≤109。
思路
1 , 1 0 9 \] \[1, 10\^9\] \[1,109\] 的正整数里面, 1 1 1 无法被连续整数序列表示,剩余所有的数都可以被以 1 1 1 或 0 0 0 1 1 1 为中心的连续整数序列表示。例如,
* 2 2 2 可以被表示为 − 1 -1 −1, 0 0 0, 1 1 1, 2 2 2。
* 3 3 3 可以被表示为 0 0 0, 1 1 1, 2 2 2。
* 4 4 4 可以被表示为 − 3 -3 −3, − 2 -2 −2, − 1 -1 −1, 0 0 0, 1 1 1, 2 2 2, 3 3 3, 4 4 4。
### 代码
```cpp
#include
using namespace std;
int n, a, ans = 0;
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a, ans += (a > 1);
cout << ans << endl;
return 0;
}
```
## D. 产值调整
时间限制: 1.0s
内存限制: 256.0MB
本题总分:10 分
### 问题描述
偏远的小镇上,三兄弟共同经营着一家小型矿业公司 "兄弟矿业"。公司旗下有三座矿山:金矿、银矿和铜矿,它们的初始产值分别用非负整数 A A A、 B B B 和 C C C 表示。这些矿山的产出是小镇经济的核心,支撑着三兄弟和许多矿工家庭的生计。
然而,各矿山的产值波动剧烈,有时金矿收益高而银矿、铜矿低迷,有时则相反。这种不稳定性让公司收入难以预测,也常引发兄弟间的争执。为了稳定经营,三兄弟设计了一个公平的产值调整策略,每年执行一次,每次调整时,将根据当前的产值 A A A、 B B B、 C C C,计算新产值:
1. 金矿新产值 A A A′ = ⌊ B + C 2 ⌋ = \\left \\lfloor\\frac{B + C}{2} \\right\\rfloor =⌊2B+C⌋;
2. 银矿新产值 B B B′ = ⌊ A + C 2 ⌋ = \\left \\lfloor\\frac{A + C}{2} \\right\\rfloor =⌊2A+C⌋;
3. 铜矿新产值 C C C′ = ⌊ A + B 2 ⌋ = \\left \\lfloor\\frac{A + B}{2} \\right\\rfloor =⌊2A+B⌋。
其中, ⌊ ⌋ \\lfloor\\rfloor ⌊⌋ 表示向下取整。例如, ⌊ 3.7 ⌋ = 3 \\lfloor3.7\\rfloor = 3 ⌊3.7⌋=3, ⌊ 5.2 ⌋ = 5 \\lfloor5.2\\rfloor = 5 ⌊5.2⌋=5。
计算出 A A A′、 B B B′、 C C C′ 后,同时更新: A A A 变为 A A A′, B B B 变为 B B B′, C C C 变为 C C C′,作
为下一年调整的基础。
三兄弟认为这个方法能平衡产值波动,于是计划连续执行 K K K 次调整。现在,请你帮他们计算,经过 K K K 次调整后,金矿、银矿和铜矿的产值分别是多少。
### 输入格式
输入的第一行包含一个整数 T T T ,表示测试用例的数量。
接下来的 T T T 行,每行包含四个整数 A A A, B B B, C C C, K K K,分别表示金矿、银矿和铜矿的初始产值,以及需要执行的调整次数。
### 输出格式
对于每个测试用例,输出一行,包含三个整数,表示经过 K K K 次调整后金矿、银矿和铜矿的产值,用空格分隔。
### 样例输入
2
10 20 30 1
5 5 5 3
### 样例输出
25 20 15
5 5 5
### 评测用例规模与约定
对于 30 % 30\\% 30% 的评测用例, 1 ≤ T ≤ 100 1 \\le T \\le 100 1≤T≤100, 1 ≤ A , B , C , K ≤ 1 0 5 1 \\le A, B,C, K \\le 10\^5 1≤A,B,C,K≤105。
对于 100 % 100\\% 100% 的评测用例, 1 ≤ T ≤ 1 0 5 1 \\le T \\le 10\^5 1≤T≤105, 1 ≤ A , B , C , K ≤ 1 0 9 1 \\le A, B,C, K \\le 10\^9 1≤A,B,C,K≤109。
### 思路
三个数会迅速向某个数收敛,当三个数都一样时,无论进行多少次操作,结果都不会变了。在三个数都变成一样之前暴力求解。
### 代码
```cpp
#include
using namespace std;
void solve() {
int a, b, c, k;
cin >> a >> b >> c >> k;
while (k--) {
int aa = (b + c) / 2, bb = (a + c) / 2, cc = (a + b) / 2;
a = aa, b = bb, c = cc;
if (a == b && b == c) break;
}
cout << a << " " << b << " " << c << "\n";
}
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
int T;
cin >> T;
while (T--) solve();
return 0;
}
```
## E. 画展布置
时间限制: 1.0s
内存限制: 256.0MB
本题总分:15 分
### 问题描述
画展策展人小蓝和助理小桥为即将举办的画展准备了 N N N 幅画作,其艺术价值分别为 A 1 A_1 A1, A 2 A_2 A2, ... \\ldots ..., A N A_N AN。他们需要从这 N N N 幅画中挑选 M M M 幅,并按照一定顺序布置在展厅的 M M M 个位置上。如果随意挑选和排列,艺术价值的变化可能会过于突兀,导致观众的观展体验不够流畅。
为了优化布置,他们查阅了《画展布置指南》。指南指出,理想的画展应使观众在欣赏画作时,艺术价值的过渡尽量平缓。指南建议,选择并排列 M M M 幅画,应使艺术价值的变化程度通过一个数值 L L L 来衡量,且该值越小越好。数值 L L L 的定义为:
L = ∑ i = 1 M − 1 ∣ B i 2 − B i + 1 2 ∣ L = \\sum_{i = 1}\^{M - 1}\|B_i\^2 - B_{i + 1}\^2\| L=∑i=1M−1∣Bi2−Bi+12∣
其中 B i B_i Bi 表示展厅第 i i i 个位置上画作的艺术价值。
现在,他们希望通过精心挑选和排列这 M M M 幅画作,使 L L L 达到最小值,以提升画展的整体协调性。请你帮他们计算出这个最小值是多少。
### 输入格式
输入共两行。
第一行包含两个正整数 N N N 和 M M M,分别表示画作的总数和需要挑选的画作数量。
第二行包含 N N N 个正整数 A 1 A_1 A1, A 2 A_2 A2, ... \\ldots ..., A N A_N AN,表示每幅画作的艺术价值。
### 输入样例
4 2
1 5 2 4
### 输出样例
3
### 样例用例规模与约定
对于 40 % 40\\% 40% 的评测用例, 2 ≤ M ≤ N ≤ 1 0 3 2 \\le M \\le N \\le 10\^3 2≤M≤N≤103, 1 ≤ A i ≤ 1 0 3 1 \\le A_i \\le 10\^3 1≤Ai≤103。
对于 100 % 100\\% 100% 的评测用例, 2 ≤ M ≤ N ≤ 1 0 5 2 \\le M \\le N \\le 10\^5 2≤M≤N≤105, 1 ≤ A i ≤ 1 0 5 1 \\le A_i \\le 10\^5 1≤Ai≤105。
### 输出格式
输出一个整数,表示 L L L 的最小值。
### 思路
* 对于选定的若干个数,一定按照大小排序一定最优。
* 对于 i \< j i \< j i\
using namespace std;
#define int long long
const int N = 1e5 + 10;
int n, m, a[N], sum[N], ans = LLONG_MAX;
signed main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> a[i];
sort(a + 1, a + n + 1);
for (int i = 2; i <= n; i++)
sum[i] = sum[i - 1] + a[i] * a[i] - a[i - 1] * a[i - 1];
for (int l = 1; l + m - 1 <= n; l++) {
int r = l + m - 1;
ans = min(ans, sum[r] - sum[l]);
}
cout << ans << endl;
return 0;
}
```
## F. 水质检测
时间限制: 1.0s
内存限制: 256.0MB
本题总分:15 分
### 问题描述
小明需要在一条 2 × n 2 \\times n 2×n 的河床上铺设水质检测器。在他铺设之前,河床上已经存在一些检测器。如果两个检测器上下或者左右相邻,那么这两个检测器就是互相连通的。连通具有传递性,即如果 A A A 和 B B B 连通, B B B 和 C C C 连通,那么 A A A 和 C C C 也连通。现在他需要在河床上增加铺设一些检测器使得所有的检测器都互相连通。他想知道最少需要增加铺设多少个检测器?
### 输入格式
输入共两行,表示一个 2 × n 2 \\times n 2×n 的河床。
每行一个长度为 n n n 的字符串,仅包含 `#` 和 `.`,其中 `#` 表示已经存在的检测器,`.` 表示空白。
### 输出格式
输出共 1 1 1 行,一个整数表示答案。
### 样例输入
.##.....#
.#.#.#...
### 样例输出
5
### 说明/提示
#### 样例说明
其中一种方案:
.###....#
.#.######
增加了 5 个检测器。
#### 评测用例规模与约定
对于 100 % 100\\% 100% 的评测用例,保证 n ≤ 1000000 n \\leq 1000000 n≤1000000。
## H. 装修报价
### 题目描述
老王计划装修房子,于是联系了一家装修公司。该公司有一套自动报价系统,只需用户提供 N N N 项装修相关费用 A 1 , A 2 , ... , A N A_1, A_2, \\dots , A_N A1,A2,...,AN,系统便会根据这些费用生成最终的报价。
然而,当老王提交数据后,他发现这套系统的运作方式并不透明:系统只会给出一个最终报价,而不会公开任何运算过程或中间步骤。
公司对此解释称,这套系统会依据某种内部算法,在每对相邻数字之间插入 + + +(加法)、 − - −(减法)或 ⊕ \\oplus ⊕(异或)运算符,并按照特定优先级规则计算结果:异或运算优先级最高,其次是加减。但由于保密性,具体的运算符组合以及中间过程都不会对外公开。
为了验证系统报价是否合理,老王决定模拟其运作方式,尝试每种可能的运算符组合,计算出所有可能出现的结果的总和。如果最终报价明显超出这个范围,他就有理由怀疑系统存在异常或误差。只是老王年事已高,手动计算颇为吃力,便向你求助。
现在,请你帮老王算出所有可能的结果的总和。由于该总和可能很大,你只需提供其对 1 0 9 + 7 10\^9+7 109+7 取余后的结果即可。
### 输入格式
第一行输入一个整数 N N N,表示装修相关费用的项数。
第二行输入 N N N 个非负整数 A 1 , A 2 , ... , A N A_1, A_2, \\dots , A_N A1,A2,...,AN,表示各项费用。
### 输出格式
输出一个整数,表示所有可能的总和对 1 0 9 + 7 10\^9 + 7 109+7 取余后的结果。
### 样例输入
3
0 2 5
### 样例输出
11
### 说明/提示
对于输入样例中的三个数 A = \[ 0 , 2 , 5 \] A = \[0, 2, 5\] A=\[0,2,5\],所有可能的运算符组合共有 9 9 9 种。计算结果如下:
0 ⊕ 2 ⊕ 5 = 7 0 \\oplus 2 \\oplus 5 = 7 0⊕2⊕5=7
0 ⊕ 2 + 5 = 7 0 \\oplus 2 + 5 = 7 0⊕2+5=7
0 ⊕ 2 − 5 = − 3 0 \\oplus 2 - 5 = -3 0⊕2−5=−3
0 + 2 ⊕ 5 = 7 0 + 2 \\oplus 5 = 7 0+2⊕5=7
0 + 2 + 5 = 7 0 + 2 + 5 = 7 0+2+5=7
0 + 2 − 5 = − 3 0 + 2 - 5 = -3 0+2−5=−3
0 − 2 ⊕ 5 = − 7 0 - 2 \\oplus 5 = -7 0−2⊕5=−7
0 − 2 + 5 = 3 0 - 2 + 5 = 3 0−2+5=3
0 − 2 − 5 = − 7 0 - 2 - 5 = -7 0−2−5=−7
所有结果的总和为:
7 + 7 + ( − 3 ) + 7 + 7 + ( − 3 ) + ( − 7 ) + 3 + ( − 7 ) = 11 7 + 7 + (-3) + 7 + 7 + (-3) + (-7) + 3 + (-7) = 11 7+7+(−3)+7+7+(−3)+(−7)+3+(−7)=11
11 11 11 对 1 0 9 + 7 10\^9 + 7 109+7 取余后的值依然为 11 11 11,因此,输出结果为 11 11 11。
### 评测用例规模与约定
* 对于 30 % 30\\% 30% 的评测用例, 1 ≤ N ≤ 13 1 \\leq N \\leq 13 1≤N≤13, 0 ≤ A i ≤ 1 0 3 0 \\leq A_i \\leq 10\^3 0≤Ai≤103。
* 对于 60 % 60\\% 60% 的评测用例, 1 ≤ N ≤ 1 0 3 1 \\leq N \\leq 10\^3 1≤N≤103, 0 ≤ A i ≤ 1 0 5 0 \\leq A_i \\leq 10\^5 0≤Ai≤105。
* 对于 100 % 100\\% 100% 的评测用例, 1 ≤ N ≤ 1 0 5 1 \\leq N \\leq 10\^5 1≤N≤105, 0 ≤ A i ≤ 1 0 9 0 \\leq A_i \\leq 10\^9 0≤Ai≤109。
### 思路
* 每一种组合真正对答案有贡献的是一段异或的前缀,如果设计加减的运算会相互抵消,比如 0 ⊕ 2 − 3 0 \\oplus 2 - 3 0⊕2−3,一定会存在一个 0 ⊕ 2 + 3 0 \\oplus 2 + 3 0⊕2+3,后面的加 + 3 +3 +3 跟 − 3 -3 −3 就抵消掉了。
* 异或前缀 i i i 对答案贡献的数量是 2 × 3 n − i − 1 2 \\times 3\^{n - i - 1} 2×3n−i−1。
### 代码
```cpp
#include
using namespace std;
#define int long long
const int N = 1e5 + 10, mod = 1e9 + 7;
int n, a[N], pre[N], pw3[N];
signed main() {
ios::sync_with_stdio(false); cin.tie(nullptr);
cin >> n;
pw3[0] = 1;
for (int i = 1; i <= n; i++) {
cin >> a[i];
pw3[i] = pw3[i - 1] * 3 % mod;
pre[i] = pre[i - 1] ^ a[i];
}
int ans = 0;
for (int i = 1; i < n; i++) {
ans = (ans + (pre[i] * 2 % mod) * pw3[n - i - 1] % mod) % mod;
}
ans = (ans + pre[n]) % mod;
cout << ans << endl;
return 0;
}
```
## 快读模板
```cpp
inline int read() {
int x = 0, f = 1; char c = getchar();
while (c < '0' || c > '9') {
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
}
```
如果题目中有的变量需要用 long long 的话,可以直接在宏里面把 int 扩展到 long long,这样比较方便(如下图)。
```cpp
#include
using namespace std;
#define int long long
inline int read() {
int x = 0, f = 1; char c = getchar();
while (c < '0' || c > '9') {
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
}
// 代码
signed main() {
// 代码
return 0;
}
```
## 对拍代码
整个对拍需要以下文件。bf.cpp文件里是暴力代码,std.cpp文件里是用了算法的代码,data.cpp用来生成输入样例,pai.cpp用来比较bf.cpp和stdcpp.out的结果是否相同。
注意:每次更改bf.cpp,std.cpp或data.cpp之后都需要重新编译之后再运行pai.cpp进行对拍。
接下来以输出 a + b 的程序来说明。

### bf.cpp
```cpp
#include
using namespace std;
int main() {
int a, b, oup = 0;
cin >> a >> b;
for (int i = 1; i <= a; i++) oup++;
for (int i = 1; i <= b; i++) oup++;
cout << oup;
return 0;
}
```
### std.cpp
```cpp
#include
using namespace std;
int main() {
int a, b;
cin >> a >> b;
if (a > 0) cout << a << endl;
cout << a + b << endl;
return 0;
}
```
### data.cpp
```cpp
#include
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rand(int l, int r) {
return uniform_int_distribution(l, r)(rng);
}
int main() {
srand(time(0));
int a = rand(1, 100000000), b = rand(1, 100000000); // 随机生成两个数字
cout << a << ' ' << b << endl; // 按照格式输出
return 0;
}
```
### pai.cpp
可以不用自己创建txt文件,编译运行一次 pai.cpp 之后会自动生成相应 txt 文件。
```cpp
#include
using namespace std;
int main() {
int t = 1;
while (1) {
printf("test%d: ", t++);
system("data.exe > in.txt"); // 用 data.exe 生成输入样例,并存入 in.txt 文件中
system("std.exe < in.txt > stdout.txt");
// 将 in.txt 文件中的输入样例用来测试 std.cpp 中的代码,并将结果输出到 stdout.txt 文件中
system("bf.exe < in.txt > bfout.txt");
// 将 in.txt 文件中的输入样例用来测试 bf.cpp 中的代码,并将结果输出到 bf.out 文件中
// 比较 stdout.txt 和 bfout.txt 文件是否一样,一样返回 false,不一样返回 true
if (system("fc stdout.txt bfout.txt")) return 0;
}
}
```
下图是 pai.cpp 运行后的输出结果,会显示 WA 和输出不一样的地方。

如果输出样例一样的话,会一直显示找不到差异。

这个时候接着写下一道题就好了,让它在后台接着运行,有可能后面会出现不一样的地方。