蓝桥杯2025 CA组
A [蓝桥杯 2025 省 A] 寻找质数
根据质数的定义,暴力就能找到
B [蓝桥杯 2025 省 A] 黑白棋
两种方法:
- 人工填补 和玩数独一样
- dfs剪枝,亲测相当的快
- 手写二十几个for也不是不可以
C [蓝桥杯 2025 省 A] 抽奖
纯模拟了,注意读题,把握细节
点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n,m;
int lt[5]={0,1,1,1};
const int maxn=1e3+10;
int a[maxn],b[maxn],c[maxn];
int p(int x){
if(x<=n) return x;
return x%n==0?n:x%n;
}
long long ans=0;
int main(){
cin>>n;
for(int i=1;i<=n;++i) cin>>a[i];
for(int i=1;i<=n;++i) cin>>b[i];
for(int i=1;i<=n;++i) cin>>c[i];
cin>>m;
for(int i=1;i<=m;++i){
int x,y,z;cin>>x>>y>>z;
lt[1]=p(lt[1]+x);
lt[2]=p(lt[2]+y);
lt[3]=p(lt[3]+z);
int val[5]={0,a[lt[1]],b[lt[2]],c[lt[3]]};
int cnt=0;
if(val[1]==val[2]-1 && val[2]==val[3]-1)
cnt+=200;
else if(val[1]==val[2] && val[2]==val[3])
cnt+=200;
else {
sort(val+1,val+4);
if(val[1]==val[2]-1 && val[2]==val[3]-1)
cnt+=100;
if(val[1]==val[2] || val[3]==val[2] )
cnt+=100;
}
ans+=cnt;
}
cout<<ans<<endl;
}
D [蓝桥杯 2025 省 A] 红黑树
赛时想麻烦了还是.
这里查点,其实相当类似于线段树查询
向左传递就是父子相同,向右传递就是父子不同
因为深度最多为30,所以不会超时
点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n;
int d,x;
void dfs(int u,int l,int r,int dep,bool book){
int mid=(l+r)>>1;
if(d==dep){
if(book) puts("RED");
else puts("BLACK");
return ;
}
if(x<=mid)
dfs(u*2,l,mid,dep+1,book);
else
dfs(u*2+1,mid+1,r,dep+1,!book);
}
int main(){
cin>>n;
for(int i=1;i<=n;++i){
cin>>d>>x;
dfs(1,1,1<<(d-1),1,1);
}
return 0;
}
E [蓝桥杯 2025 省 A] 黑客
高中的排列组合知识:
对于一个有重复元素的排列,设重复的元素i的重复次数为\(cnt_i\),总的元素个数为n
所以有:\(\frac{n!}{\prod (cnt_i!)}\)个不同的排列
需要取余,可以求逆元,提前与处理好,防止超时
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=1e9+7;
const ll maxn=5e5+10;
ll jc[maxn]={1},invjc[maxn];//jc是阶乘,invjc是阶乘的逆
ll ans=0;
ll cunt[maxn];
ll tot,n;
ll qpow(ll a,ll b){
ll cnt=1;
ll base=a;
while(b){
if(b&1) cnt=(cnt*base)%mod;
base=(base%mod*base%mod)%mod;
b>>=1;
}
return cnt;
}
ll inv(ll x){//求逆
return qpow(x,mod-2);
}
int main(){
cin>>tot;n=tot-2;
for(int i=1;i<=maxn-10;++i)//递推求阶乘和逆
jc[i]=jc[i-1]*i%mod;
for(int i=1;i<=maxn-10;++i)
invjc[i]=inv(jc[i]);
for(int i=1;i<=tot;++i){
int x;cin>>x;
cunt[x]++;
}
for(int i=1;i<=n;++i){
if(n%i || !cunt[i] || !cunt[n/i]) continue;
cunt[i]--;cunt[n/i]--;
ll now=jc[n];
for(int j=1;j<=maxn-10;++j){
if(cunt[j])
now=now*invjc[cunt[j]]%mod;
}
ans=(ans+now)%mod;
cunt[i]++;cunt[n/i]++;
}
cout<<ans<<endl;
}
F [蓝桥杯 2025 省 A] 好串的数目
点击查看代码
#include<bits/stdc++.h>
using namespace std;
string s;
int n;
#define ll long long
int main(){
cin>>s;n=s.length();s=" "+s;
int last=0;long long ans=0;
for(int i=1;i<=n;++i){
int len=1;
while(s[i]==s[i+1] || s[i]==s[i+1]-1 && i<n){
++len;++i;
}
ans+=(ll)(1+len)*len/2;
ans+=(ll)len*last;
last=(ll)len;
}
cout<<ans<<endl;
return 0;
}
G [蓝桥杯 2025 省 A] 地雷阵
中学的几何知识,用asin和atan算一下角度,每个地雷都会覆盖一段角度区间,这里就类似于线段覆盖区间,可以用差分
每个地雷的角度范围计算:
圆心到坐标原点直线l:\(\theta=arctan(y/x)\),
切线和l的夹角\(\alpha=arcsin(\frac{r}{(x^2+y^2)})\)
所以角度范围\([\theta+\alpha,\theta-\alpha]\)
由于计算后是小数,为确保精度,可以扩大1e7倍.(但是这个在洛谷上没能全过,不知道有没有大佬给我修改一下
点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n;
int num[3000100];
int main(){
cin>>n;
double up=3.1415926/2*1000000;
for(int i=1;i<=n;++i){
double x,y,r;
cin>>x>>y>>r;
double len=sqrt(x*x+y*y);
double s=atan(y/x);
double sup=(s+asin(r/len))*1000000;
double sdown=(s-asin(r/len))*1000000;
sdown=max(0.0,sdown);
sup=min(up,sup);
num[(int)sup+1]-=1;
num[(int)sdown]+=1;
}
int cnt=0;
int tot=0;
for(int i=0;i<=up;++i){
tot+=num[i];
if(tot==0) ++cnt;
}
double ans=cnt*1.0/up;
cout<<fixed<<setprecision(3)<<ans<<endl;
return 0;
}
H [蓝桥杯 2025 省 A] 扫地机器人
貌似是基环树,忘了,待更......

浙公网安备 33010602011771号