P12130 [蓝桥杯 2025 省 B] 移动距离 - 洛谷
题目描述
小明初始在二维平面的原点,他想前往坐标 (233,666)。在移动过程中,他只能采用以下两种移动方式,并且这两种移动方式可以交替、不限次数地使用:
- 水平向右移动,即沿着 x 轴正方向移动一定的距离。
- 沿着一个圆心在原点 (0,0)、以他当前位置到原点的距离为半径的圆的圆周移动,移动方向不限(即顺时针或逆时针移动不限)。
在这种条件下,他到达目的地最少移动多少单位距离?你只需要输出答案四舍五入到整数的结果。
输入格式
无
输出格式
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只需要编写一个程序输出这个整数,输出多余的内容将无法得分。
输入输出样例
无
题解
最少移动单位距离=沿 x 轴正方向移动的距(半径)+弧长
弧长=θ*半径
tanθ=666/233
θ=arctan(666/233)

正解1
答案1576。
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
double l=sqrt(233*233+666*666);
//(0*l)+l
double s=((double)atan2(666,233)+1)*l;
cout<<s;
return 0;
}

四舍五入得到1576。
正解2
电脑计算器计算(考虑到许多人可能没了解过C++的 tan 和 arctan)
在计算器中,rad、grad和deg是用于表示角度的不同单位:
deg :是角度制的单位,即我们通常所说的角度。一个圆周被分为360度,1度等于60分,1分等于60秒。例如,直角是90度,平角是180度。
rad :是弧度制的单位。它的定义是:弧长等于半径的弧所对的圆心角为1弧度。一个圆周的弧度是2π,所以360度等于2π弧度,1度约等于0.01745弧度。在数学和科学计算中,弧度制在很多公式和计算中更为方便,例如三角函数的计算。
grad:是百分度制的单位,也称为"梯度"或"百分度"。一个圆周被分为400 grad,所以1 grad等于0.9度,直角是100 grad。百分度制在一些工程和测量领域有一定应用。
那么如何用计算器计算arctan(666/233)呢?
1.任务栏搜索框搜索calculator

也可以在Windows系统中,使用命令提示符打开计算器:
按下键盘上的Win+R键,打开运行窗口,在运行窗口中输入"cmd",然后按回车键,打开命令提示符窗口。

在命令提示符窗口中输入"calc",再按回车键,即可打开计算器应用程序。

这样就可以打开了

2.将DEG改为RAD


3.计算括号里面的

4.点击 "三角学",再点击"2nd",再点击"tan^-1"。
在计算器上,"2nd"键通常表示"第二功能"或"切换功能",用于调用按键上标注的第二种功能。
在计算器中,"tan⁻¹"表示反正切函数。

5.得到arctan(666/233)的结果1.2342......

将结果+1后 再×sqrt(233 * 233 + 666 * 666)四舍五入可得1576。
P12131 [蓝桥杯 2025 省 B] 客流量上限 - 洛谷
题目描述
一家连锁旅馆在全国拥有 2025 个分店,分别编号为 1 至 2025。随着节日临近,总部决定为每家分店设定每日客流量的上限,分别记作 A1,A2,...,A2025。这些上限并非随意分配,而是需要满足以下约束条件:
- A1,A2,...,A2025 必须是 1 至 2025 的一个排列,即每个 Ai 均是 1 至 2025 之间的整数,且所有 Ai 互不相同。
- 对于任意分店 i 和 j(1≤i,j≤2025,i 可等于 j),它们的客流量上限 Ai 和 Aj 的乘积不得超过 i×j+2025。
这些约束旨在平衡各分店客流压力,确保服务质量和运营稳定性。
现在,请你计算这样的分配方案究竟有多少种。由于答案可能很大,你只需输出其对 109+7 取余后的结果即可。
输入格式
无
输出格式
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只需要编写一个程序输出这个整数,输出多余的内容将无法得分。
输入输出样例
无
题解
这道题用到了快速幂算法,可以看看🐖波主页的"逆元,快速幂模板"。
看了许多题解,还是不太理解,谁来解析一下。



对于i < 1013的分店,每个分店的客流量上限Ai有两种选择i或i + 1,而这样的分店有1012个。根据排列组合的乘法原理,总的分配方案数就是2^1012。由于答案可能很大,所以通过快速幂函数计算2^1012mod(10^9 + 7),并输出该结果。
cpp
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
int kuaisumi(ll a,ll b)
{
ll res=1;
while(b>0)
{
if(b&1)
{
res=(res*a)%mod;
}
a=(a*a)%mod;
b>>=1;
}
return res;
}
int main()
{
ll sum=kuaisumi(2,1012);
cout<<sum<<endl;
return 0;
}
答案781448427。
P12132 [蓝桥杯 2025 省 B] 可分解的正整数 - 洛谷
题目背景
本站蓝桥杯 2025 省赛测试数据均为洛谷自造,与官方数据可能存在差异,仅供学习参考。
题目描述
定义一种特殊的整数序列,这种序列由连续递增的整数组成,并满足以下条件:
- 序列长度至少为 3。
- 序列中的数字是连续递增的整数(即相邻元素之差为 1),可以包括正整数、负整数或 0。
例如,[1,2,3]、[4,5,6,7] 和 [−1,0,1] 是符合条件的序列,而 [1,2](长度不足)和 [1,2,4](不连续)不符合要求。
现给定一组包含 N 个正整数的数据 A1,A2,...,AN。如果某个 Ai 能够表示为符合上述条件的连续整数序列中所有元素的和,则称 Ai 是可分解的。
请你统计这组数据中可分解的正整数的数量。
输入格式
输入的第一行包含一个正整数 N,表示数据的个数。
第二行包含 N 个正整数 A1,A2,...,AN,表示需要判断是否可分解的正整数序列。
输出格式
输出一个整数,表示给定数据中可分解的正整数的数量。
输入输出样例
输入 #1复制
3
3 6 15
输出 #1复制
3
说明/提示
样例说明
- Ai=3 是可分解的,因为 [0,1,2] 的和为 0+1+2=3。
- Ai=6 是可分解的,因为 [1,2,3] 的和为 1+2+3=6。
- Ai=15 是可分解的,因为 [4,5,6] 的和为 4+5+6=15。
所以可分解的正整数的数量为 3。
评测用例规模与约定
- 对于 30% 的评测用例,1≤N≤100,1≤Ai≤100。
- 对于 100% 的评测用例,1≤N≤105,1≤Ai≤109。
解题思路
只有1不可分!
0:-1,0,1
x: -(x-1) , -(x-2),... ,0,1,2,3,...,x-1,x
正解:
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
vector<int>a(n);
for(int i=0;i<n;i++)
{
cin>>a[i];
}
long long cnt=0;
for(int i=0;i<n;i++)
{
if(a[i]!=1)
{
cnt++;
}
}
cout<<cnt;
return 0;
}
P12133 [蓝桥杯 2025 省 B] 产值调整 - 洛谷
题目描述
偏远的小镇上,三兄弟共同经营着一家小型矿业公司"兄弟矿业"。公司旗下有三座矿山:金矿、银矿和铜矿,它们的初始产值分别用非负整数 A、B 和 C 表示。这些矿山的产出是小镇经济的核心,支撑着三兄弟和许多矿工家庭的生计。
然而,各矿山的产值波动剧烈,有时金矿收益高而银矿、铜矿低迷,有时则相反。这种不稳定性让公司收入难以预测,也常引发兄弟间的争执。为了稳定经营,三兄弟设计了一个公平的产值调整策略,每年执行一次,每次调整时,将根据当前的产值 A、B、C,计算新产值:

计算出 A′、B′、C′ 后,同时更新:A 变为 A′,B 变为 B′,C 变为 C′,作为下一年调整的基础。
三兄弟认为这个方法能平衡产值波动,于是计划连续执行 K 次调整。现在,请你帮他们计算,经过 K 次调整后,金矿、银矿和铜矿的产值分别是多少。
输入格式
输入的第一行包含一个整数 T,表示测试用例的数量。
接下来的 T 行,每行包含四个整数 A,B,C,K,分别表示金矿、银矿和铜矿的初始产值,以及需要执行的调整次数。
输出格式
对于每个测试用例,输出一行,包含三个整数,表示经过 K 次调整后金矿、银矿和铜矿的产值,用空格分隔。
输入输出样例
输入 #1复制
2
10 20 30 1
5 5 5 3
输出 #1复制
25 20 15
5 5 5
说明/提示
评测用例规模与约定
- 对于 30% 的评测用例,1≤T≤10^0,1≤A,B,C,K≤10^5。
- 对于 100% 的评测用例,1≤T≤10^5,1≤A,B,C,K≤10^9。
题解
暴力(洛谷30%,蓝桥云客上通过50%):
时间复杂度 O(Tk):10^5*10^9=10^14
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
vector<int>a(t);
vector<int>b(t);
vector<int>c(t);
vector<int>k(t);
for(int i=0;i<t;i++)
{
cin>>a[i]>>b[i]>>c[i]>>k[i];
long long x1=0,x2=0,x3=0,y1=0,y2=0,y3=0;
for(int z=1;z<=k[i];z++)
{
x1=(b[i]+c[i])/2;
x2=(a[i]+c[i])/2;
x3=(a[i]+b[i])/2;
a[i]=x1;
b[i]=x2;
c[i]=x3;
}
y1=a[i];
y2=b[i];
y3=c[i];
cout<<y1<<" "<<y2<<" "<<y3<<endl;
}
return 0;
}
正解:

使用 break 语句跳出内层循环,可以避免不必要的计算,从而提高程序的运行效率 。特别是当 k[i](调整次数)比较大的时候,这种优化能显著减少计算量。
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
vector<int>a(t);
vector<int>b(t);
vector<int>c(t);
vector<int>k(t);
for(int i=0;i<t;i++)
{
cin>>a[i]>>b[i]>>c[i]>>k[i];
long long x1=0,x2=0,x3=0,y1=0,y2=0,y3=0;
for(int z=1;z<=k[i];z++)
{
if(a[i]==b[i]&&b[i]==c[i])
{
break;
}
x1=(b[i]+c[i])/2;
x2=(a[i]+c[i])/2;
x3=(a[i]+b[i])/2;
a[i]=x1;
b[i]=x2;
c[i]=x3;
}
y1=a[i];
y2=b[i];
y3=c[i];
cout<<y1<<" "<<y2<<" "<<y3<<endl;
}
return 0;
}
P12134 [蓝桥杯 2025 省 B] 画展布置 - 洛谷
题目描述
画展策展人小蓝和助理小桥为即将举办的画展准备了 N 幅画作,其艺术价值分别为 A1,A2,...,AN。他们需要从这 N 幅画中挑选 M 幅,并按照一定顺序布置在展厅的 M 个位置上。如果随意挑选和排列,艺术价值的变化可能会过于突兀,导致观众的观展体验不够流畅。
为了优化布置,他们查阅了《画展布置指南》。指南指出,理想的画展应使观众在欣赏画作时,艺术价值的过渡尽量平缓。指南建议,选择并排列 M 幅画,应使艺术价值的变化程度通过一个数值 L 来衡量,且该值越小越好。数值 L 的定义为:
L=i=1∑M−1∣Bi+12−Bi2∣
其中 Bi 表示展厅第 i 个位置上画作的艺术价值。
现在,他们希望通过精心挑选和排列这 M 幅画作,使 L 达到最小值,以提升画展的整体协调性。请你帮他们计算出这个最小值是多少。
输入格式
输入共两行。
第一行包含两个正整数 N 和 M,分别表示画作的总数和需要挑选的画作数量。
第二行包含 N 个正整数 A1,A2,...,AN,表示每幅画作的艺术价值。
输出格式
输出一个整数,表示 L 的最小值。
输入输出样例
输入 #1复制
4 2
1 5 2 4
输出 #1复制
3
说明/提示
评测用例规模与约定
- 对于 40% 的评测用例,2≤M≤N≤10^3,1≤Ai≤10^3。
- 对于 100% 的评测用例,2≤M≤N≤10^5,1≤Ai≤10^5。
解题思路
为了最小化L,我们需要选择M幅画作,并排列它们,使得相邻画作的艺术价值的平方差绝对值之和最小。观察L的定义,可以发现:

为了最小化L,我们需要让相邻画作的艺术价值尽可能接近,这样它们的平方差也会尽可能小。因此,我们可以考虑以下步骤:
-
排序:首先将所有画作的艺术价值进行排序。这样我们可以方便地选择相邻的画作,使得它们的艺术价值接近。
-
选择连续的子序列:在排序后的数组中,选择连续的M个元素。因为连续的子序列中相邻元素的差值最小,从而平方差的绝对值之和也会最小。
-
计算L的最小值:对于所有可能的连续M长度的子序列,计算对应的L值,并找到最小的那个。
暴力(洛谷50%,蓝桥云客上通过90%):
将数组a排序后直接选前m个数然后带入公式计算。
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
vector<int>a(n);
for(int i=0;i<n;i++)
{
cin>>a[i];
}
sort(a.begin(),a.end());
long long l=0;
for(int i=0;i<m-1;i++)
{
l+=abs(a[i+1]*a[i+1]-a[i]*a[i]);
}
cout<<l;
return 0;
}
正解:
枚举出所有的连续子序列,然后分别求出每个Am²-A1²的大小,边求边更新L的最小值。
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
vector<int>a(n);
for(int i=0;i<n;i++)
{
cin>>a[i];
}
sort(a.begin(),a.end());
long long l=1e18;
for(int i=0;i+m-1<n;i++)
{
l=min(l,abs((long long)a[i+m-1]*a[i+m-1]-(long long)a[i]*a[i]));
}
cout<<l;
return 0;
}
P12135 [蓝桥杯 2025 省 B] 水质检测 - 洛谷
题目描述
小明需要在一条 2×n 的河床上铺设水质检测器。在他铺设之前,河床上已经存在一些检测器。如果两个检测器上下或者左右相邻,那么这两个检测器就是互相连通的。连通具有传递性,即如果 A 和 B 连通,B 和 C 连通,那么 A 和 C 也连通。现在他需要在河床上增加铺设一些检测器使得所有的检测器都互相连通。他想知道最少需要增加铺设多少个检测器?
输入格式
输入共两行,表示一个 2×n 的河床。
每行一个长度为 n 的字符串,仅包含 # 和 .,其中 # 表示已经存在的检测器,. 表示空白。
输出格式
输出共 1 行,一个整数表示答案。
输入输出样例
输入
.##.....#
.#.#.#...
输出
5
说明/提示
样例说明
其中一种方案:
.###....#
.#.######
增加了 5 个检测器。
评测用例规模与约定
对于 100% 的评测用例,保证 n≤1000000。
题解
正解1
这道题目考察的是贪心算法 和连通性处理。我们需要在给定的2×n网格中,通过添加最少的检测器(将'.'变为'#'),使得所有现有的检测器('#')都互相连通。
算法解释
-
问题分析:检测器的连通性包括上下和左右相邻。我们需要确保所有'#'通过相邻关系连成一个整体。关键在于处理每一列的状态,并根据相邻列的状态决定需要添加的检测器数量。
-
状态定义 :使用
state变量来记录前一列的状态:-
state 1:只有第一行有'#'。
-
state 2:只有第二行有'#'。
-
state 3:两行都有'#'。
-
-
贪心策略:
-
遍历每一列,跳过两行均为'.'的列。
-
如果前一列有'#'(
pre != -1),计算当前列与前一列之间的空白列数(i - pre - 1),并累加到答案中。 -
根据当前列的状态和前一列的
state,决定是否需要额外添加检测器(例如,当state为1且当前列状态为2时,需要在中间某一列添加一个检测器使上下连通)。
-
-
关键点 :通过维护
pre和state,可以高效地计算需要填充的检测器数量,确保每次处理都是局部最优,从而得到全局最优解。
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
string a,b;
cin>>a;
cin>>b;
int ans=0;
int pre=-1;//记录上一次的特殊位置的下标
int state=-1;//代表pre所对应的状态
/* 三种state: 1 2 3
# . #
. # #
*/
/*例: 0 1 2 3 4
i
pre
. # #
. . . . .
*/
for(int i=0;i<a.size();i++)
{
if(a[i]=='.'&&b[i]=='.')continue;//这种情况直接跳过
if(pre!=-1) ans+=i-pre-1;
/* 这里需要注意pre这个变量是不多余的,
如果 continue 执行,pre = i是不会被执行的
(1) # . # ans+=1;
# . .
(2) # # ans+=0;
# .
*/
if(a[i]=='#'&&b[i]=='#')state=3;
//不用加#
/* (1) # # (2) . # (3) # #
. # # # # #
*/
else if(a[i]=='#'&&b[i]=='.')
{
if(state==2)//(2)
{
ans++;
state=3;
}
else state=1;
/* (1) # # (2) . # (3) # #
. . # . # .
*/
}
else if(a[i]=='.'&&b[i]=='#')
{
if(state==1)//(1)
{
ans++;
state=3;
}
else state=2;
/* (1) # . (2) . . (3) # .
. # # # # #
*/
}
pre=i;//随时更新
}
cout<<ans;
return 0;
}
正解2(模拟+贪心)
这里也是借鉴其他煮波的题解。
cpp
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s1, s2;
cin >> s1;
cin >> s2;
long long n = s1.size();
long long ans = 0;
s1 = " " + s1;
s2 = " " + s2;
//添加前导空格,方便索引从1开始
int l = 0, r = 0;
//分别用于记录字符串中第一个 '#' 字符出现的位置
//和最后一个 '#' 字符出现的位置,初始值都为 0
int state = -1;
//标记"初始状态"-1,这里的初始状态指i=l时的状态
/* 可以拿着样例来理解
.##.....#
.#.#.#... */
for(int i = 1; i <= n; i++)
{
if((s1[i] == '#' || s2[i] == '#') && l == 0)
{
l = i;
}
if((s1[i] == '#' || s2[i] == '#'))
{
r = i;
}
}//给l和r赋值
if(s1[l] == '.' && s2[l] == '#') state = 0;
if(s1[l] == '#' && s2[l] == '.') state = 1;
//定义状态0和状态1
//此时s1[l] == '#' && s2[l] == '#'为state=-1
for(int i = l + 1; i <= r; i++)
{
if(s1[i] == '.' && s2[i] == '.')
{
ans++;//这里状态不变,仍继承上一个状态
}
else if(s1[i] == '.' && s2[i] == '#')
{
if(state == 1)
{
ans++;
state = -1;
}
else
state = 0;
}
else if(s1[i] == '#' && s2[i] == '.')
{
if(state == 0)
{
ans++;
state = -1;
}
else
state = 1;
}
else //即两个#的情况
{
state = -1;
}
}
cout << ans;
return 0;
}
有用DFS或BFS写的拿部分分的吗?煮波借鉴一下!
P12136 [蓝桥杯 2025 省 B] 生产车间 - 洛谷
题目描述
小明正在改造一个生产车间的生产流水线。这个车间共有 n 台设备,构成以 1 为根结点的一棵树,结点 i 有权值 wi。其中叶节点的权值 wi 表示每单位时间将产出 wi 单位的材料并送往父结点,根结点的权值 wi 表示每单位时间内能打包多少单位成品,其他结点的权值 wi 表示每单位时间最多能加工 wi 单位的材料并送往父结点。
由于当前生产线中某些结点存在产能不够的问题导致生产线无法正常运行,即存在某些结点每单位时间收到的材料超过了当前结点的加工能力上限。小明计划删除一些结点使得所有结点都能正常运行。他想知道删除一些结点后根结点每单位时间内最多能打包多少单位的成品?
输入格式
输入共 n+1 行。
第一行为一个正整数 n。
第二行为 n 个由空格分开的正整数 w1,w2,...,wn。
后面 n−1 行,每行两个整数表示树上的一条边连接的两个结点。
输出格式
输出共一行,一个整数代表答案。
输入输出样例
输入
9
9 7 3 7 1 6 2 2 7
1 2
1 3
2 4
2 5
2 6
6 7
6 8
6 9
输出
8
说明/提示
样例说明
删掉结点 4、9 后生产线满足条件,根结点 1 每单位时间将打包出 8 单位的成品。
评测用例规模与约定
- 对于 20% 的评测用例,2≤n≤100。
- 对于 100% 的评测用例,2≤n≤1000,1≤wi≤1000。
题解

暴力(洛谷50%,蓝桥云客上通过70%):

考虑到初始根节点的权值可能就是每单位时间内最多能打包的单位的成品的数量,所以直接尝试输出根结点的权值。
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
vector<int>w(n);
for(int i=0;i<n;i++)
{
cin>>w[i];
}
vector<int>a(n-1),b(n-1);
for(int i=0;i<n-1;i++)
{
cin>>a[i]>>b[i];
}
cout<<w[0];
return 0;
}
P12137 [蓝桥杯 2025 省 B] 装修报价 - 洛谷
题目描述
老王计划装修房子,于是联系了一家装修公司。该公司有一套自动报价系统,只需用户提供 N 项装修相关费用 A1,A2,...,AN,系统便会根据这些费用生成最终的报价。
然而,当老王提交数据后,他发现这套系统的运作方式并不透明:系统只会给出一个最终报价,而不会公开任何运算过程或中间步骤。
公司对此解释称,这套系统会依据某种内部算法,在每对相邻数字之间插入 +(加法)、−(减法)或 ⊕(异或)运算符,并按照特定优先级规则计算结果:异或运算优先级最高,其次是加减。但由于保密性,具体的运算符组合以及中间过程都不会对外公开。
为了验证系统报价是否合理,老王决定模拟其运作方式,尝试每种可能的运算符组合,计算出所有可能出现的结果的总和。如果最终报价明显超出这个范围,他就有理由怀疑系统存在异常或误差。只是老王年事已高,手动计算颇为吃力,便向你求助。
现在,请你帮老王算出所有可能的结果的总和。由于该总和可能很大,你只需提供其对 109+7 取余后的结果即可。
输入格式
第一行输入一个整数 N,表示装修相关费用的项数。
第二行输入 N 个非负整数 A1,A2,...,AN,表示各项费用。
输出格式
输出一个整数,表示所有可能的总和对 109+7 取余后的结果。
输入输出样例
输入
3
0 2 5
输出
11
说明/提示
对于输入样例中的三个数 A=[0,2,5],所有可能的运算符组合共有 9 种。计算结果如下:
0⊕2⊕5=70⊕2+5=70⊕2−5=−30+2⊕5=70+2+5=70+2−5=−30−2⊕5=−70−2+5=30−2−5=−7
所有结果的总和为:
7+7+(−3)+7+7+(−3)+(−7)+3+(−7)=11
11 对 109+7 取余后的值依然为 11,因此,输出结果为 11。
评测用例规模与约定
- 对于 30% 的评测用例,1≤N≤13,0≤Ai≤103。
- 对于 60% 的评测用例,1≤N≤103,0≤Ai≤105。
- 对于 100% 的评测用例,1≤N≤105,0≤Ai≤109。
木写。。。