蓝桥杯2025年第十六届省赛真题
1.可分解的正整数

本题结论:任何大于1的正整数都可表示为至少三个连续整数的和
所以只需要判断 A i Ai Ai是否大于1就可以
C语言
c
#include <stdio.h>
int main(){
int N;
scanf("%d",&N);
int x;
int i;
int count=0;
for(i=0;i<N;i++){
scanf("%d",&x);
if(x>1) count++;
}
printf("%d",count);
return 0;
}
C++
c++
#include <iostream>
using namespace std;
int main(){
int N;
cin >> N;
int x;
int i;
int count=0;
for(i=0;i<N;i++){
cin >> x;
if(x>1) count++;
}
cout << count;
return 0;
}
- 扩展 :有关"连续整数和"的完整定理
假设连续整数序列从 a a a开始,长度为 k k k ( k ≥ 2 ) (k≥2) (k≥2),和为 S S S,根据等差数列求和公式 , S = k × a + k ( k + 1 ) / 2 S=k×a+k(k+1)/2 S=k×a+k(k+1)/2
👍定理一:从1开始 的连续正整数的和,S必须是三角数 ,即 S = k × ( k + 1 ) / 2 S=k×(k+1)/2 S=k×(k+1)/2
👍定理二:至少两个连续正整数 的和,S不是2的幂
👍定理三:至少三个连续整数 的和,S是大于1的整数(允许负数,也是本题的情况)
如果感兴趣可以自己根据等差数列求和公式推导一下
2.产值调整

这道题直接模拟就可以,但是有两个注意点:
- 需要用long long
- 因为只要迭代几次,三个数就会相等,如果不加三数相等后跳出循环的条件,就会因为k值过大,而有一个测试点超时
C语言
c
#include <stdio.h>
int main(){
int T;
scanf("%d",&T);
while(T--){
long long a,b,c;
int k;
scanf("%lld %lld %lld %d",&a,&b,&c,&k);
while(k--){
long long a1=(b+c)/2;
long long b1=(a+c)/2;
long long c1=(a+b)/2;
a=a1;
b=b1;
c=c1;
if(a==b&&a==c&&b==c) break;
}
printf("%lld %lld %lld\n",a,b,c);
}
return 0;
}
C++
c++
#include <iostream>
using namespace std;
int main(){
int T;
cin >> T;
while(T--){
long long a,b,c;
int k;
cin>>a>>b>>c>>k;
int i;
while(k--){
long long a1=(b+c)/2;
long long b1=(a+c)/2;
long long c1=(a+b)/2;
a=a1;
b=b1;
c=c1;
if(a==b&&a==c&&b==c) break;
}
cout<<a<<" "<<b<<" "<<c<<endl;
}
}
3.画展布置

如果序列单调递增 , L = B M 2 − B 1 2 L=B^2_M-B^2_1 L=BM2−B12,此时 L L L最小
所以先将M幅画进行排序,利用定长滑动窗口求最小值(N中的哪M幅画L值最小)
c++
c++
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;
int main(){
int N,M;
cin>>N>>M;
vector<long long> A(N);
for(int i=0;i<N;i++){
cin>>A[i];
}
if(M==1){
cout<<0<<endl;
return 0;
}
sort(A.begin(),A.end());
long long ans=LLONG_MAX;
for(int i=0;i<=N-M;i++){
long long diff=A[i+M-1]*A[i+M-1]-A[i]*A[i];
if(diff<ans) ans=diff;
}
cout<<ans<<endl;
return 0;
}
- 感触
- c++常用头文件就那么几个,如果实在记不住对应关系,就背下来全写上
- 还是多想着用
long long吧