蓝桥杯2025 CA组

A [蓝桥杯 2025 省 A] 寻找质数

根据质数的定义,暴力就能找到

B [蓝桥杯 2025 省 A] 黑白棋

两种方法:

  1. 人工填补 和玩数独一样
  2. dfs剪枝,亲测相当的快
  3. 手写二十几个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] 扫地机器人

貌似是基环树,忘了,待更......

posted @ 2025-04-23 21:47  归游  阅读(181)  评论(0)    收藏  举报