第十六届蓝桥杯大赛软件赛省赛第二场 C/C++ 大学 A 组

比赛还没有开始,竟然忘记写using namespace std; //debug半天没看明白 (平时cv多了

然后就是忘记那个编译参数,(好惨的开局

编译参数-std=c++11

以下都是赛时所写代码,赛时无聊时把思路都打上去了(除了倒数第二题,多加了一个栈为空的判断)

1~7题洛谷简单测了一下都通过了

交题链接,这个是民间数据
https://www.luogu.com.cn/problem/list?tag=62%7C363&page=2

A

#include<bits/stdc++.h>

using namespace std;
#define fi first
#define se second
int const N=2e5+7,M=2e6+7;

int n,m;
int a[N];
string s,t;

int main(){
//	init();
	//250 200 240
	//长50 宽40 高30
	//观察可以发现大箱子调整为长250,宽200,高240
	//那么对于每一层50*40的小箱子可以正好铺满250*200的大箱子
	//高240又恰好为30的倍数,那么直接就是大箱子体积除小箱子体积 
	int n=200*240*250/30/40/50;	cout<<n<<endl; 
	
	return 0;
}//200

B:

#include<bits/stdc++.h>

using namespace std;
typedef long long LL;
#define fi first
#define se second
int const N=2e5+7,M=2e6+7;

int n,m;
int a[N];
string s,t;

int main(){
	int x=20255202,y=10244201;
	LL st=sqrt(x)+1; //计算最小的满足x的平方数 
//	
	LL ans=0;
	//上边界只需要枚举到y, 
	//只需要枚举到y,y后面的不合法 
	for(LL i=st;i<=y;i++){	//枚举平方数 
		//x一定为平方数 
		LL n=i*i-x,k=n+y; //先计算n,在计算y+n 
		LL temp=sqrtl(k);	 
		if(temp*temp==k){ //判断y+n是否为平方数 
			ans++;
		}
	}
	cout<<ans<<endl;
	
	return 0;
}
//14

C:

#include<bits/stdc++.h>

using namespace std;
#define fi first
#define se second
int const N=2e5+7,M=2e6+7;

int n,m;
int a[N];
string s="LANQIAO";

//LANQIAOLANQIAOLANQIAO
int main(){
	cin>>n>>m;
	string t(m,0);
	
	int ans=0;
	//直接枚举O(n*m) 
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			t[j]=s[(i+j)%7];
			if(t[j]=='A') ans++;
		}
	}
	cout<<ans<<endl;
	return 0;
}

D:

#include<bits/stdc++.h>

using namespace std;
#define fi first
#define se second
int const N=2e5+7,M=2e6+7;

int n,m;
string s,t;

int main(){
	cin>>s;
	n=s.size();
	
	vector<int>a,b;
	for(int i=0;i<n;i++){
		if(s[i]=='A') a.push_back(i);
		else b.push_back(i);
	} 
	
	int na=a.size(),nb=b.size();
	int  i=0,j=nb-1;
	
	
	//贪心让前面的A和后面的B匹配 
	int cnt=0;
	while(i<na&&j>=0&&a[i]<b[j]){ 
//		cout<<a[i]<<" "<<b[j]<<endl;
		cnt+=2;
		i++;
		j--;
	}
	
	cout<<n-cnt<<"\n";
	
	return 0;
}

/*
BABAABBA
ans=4

ABAB

AB
*/

E:

#include<bits/stdc++.h>

using namespace std;
typedef long long LL;
#define fi first
#define se second
int const N=2e5+7,M=2e6+7;

int n,m;
int x,y,z;
int a[N];
string s,t;
vector<int>g[N];
LL dep[N];

void dfs(int x,int fa,int k){
	dep[k]+=a[x];
	for(int y:g[x]) if(y!=fa) dfs(y,x,k+1);
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",a+i);
	for(int i=1;i<n;i++){
		scanf("%d%d",&x,&y);
		g[x].push_back(y);
		g[y].push_back(x);
	}
	dfs(1,-1,0);
	
	
	//不超过k条边,那么距离小于k条边的都是合法的节点,最后累加即可 
	LL ans=0;
	for(int i=0;i<=min(n,2*m);i++) ans+=dep[i];
	cout<<ans<<endl; 
	
	return 0;
}

/*
8 2
6 3 3 1 5 4 3 4
1 2
2 3
2 4
4 5
5 6
6 7
7 8


ans=22


4 1
1 1 1 1
1 2
2 3

3 4

*/

F:hash记录前缀写了单hash和双hash,赛时交的双hash

#include<bits/stdc++.h>

using namespace std;
typedef long long LL;
#define fi first
#define se second
int const N=2e5+7,M=2e6+7;

int n,m;
int const base1=37,mod1=2e9+11;
const int base2=13331,mod2=1e9+1e8+9;
string s,t;
int p[N],p2[N];

/*
用i从小到大枚举用hash表记录前缀所有的字符串,然后判断以j开始的反字符串,前面出现多少个 
直接用key等于string会tle
那么我们可以使用hash字符串记录,时间复杂度n*m*log(mp) 
*/ 


void solve2(){//双hash 
	p[0]=p2[0]=1;
	for(int i=1;i<=n;i++){
		p[i]=1LL*p[i-1]*base1%mod1;
		p2[i]=1LL*p2[i-1]*base2%mod2;
	}
	
	map<LL,int>mp;
	LL ans=0;
	for(int i=0;i<n;i++){		
		//向后枚举
		LL v=0,v2=0;
		for(int j=i;j<n;j++){
			v=(1LL*v*base1+(s[j]=='0'?'1':'0'))%mod1;
			v2=(1LL*v2*base2+(s[j]=='0'?'1':'0'))%mod2;
			LL bas=(v<<32)|v2;
			if(mp.count(bas)) ans+=mp[bas];
		} 
		
		//向前枚举 
		v=0; v2=0;
		for(int j=i;j>=0;j--){
			v=(v+1LL*p[i-j]*s[j])%mod1;
			v2=(v2+1LL*p2[i-j]*s[j])%mod2;
			LL bas=(v<<32)|v2;
			mp[bas]++;
		}
//		cout<<ans<<endl;
		
	}
	cout<<ans<<endl;	
	return;
} 

void solve(){ //单hash 
	p[0]=1;
	for(int i=1;i<=n;i++) p[i]=1LL*p[i-1]*base1%mod1;
	
	map<int,int>mp;
	LL ans=0;
	for(int i=0;i<n;i++){		
		//向后枚举
		int v=0;
		for(int j=i;j<n;j++){
			v=(1LL*v*base1+(s[j]=='0'?'1':'0'))%mod1;
			if(mp.count(v)) ans+=mp[v];
		} 
		
		//向前枚举 
		v=0;
		for(int j=i;j>=0;j--){
			v=(v+1LL*p[i-j]*s[j])%mod1;
			mp[v]++;
		}
//		cout<<ans<<endl;
		
	}
	cout<<ans<<endl;	
	return;
} 

int main(){
//	init();
	
	cin>>s;
	n=s.size();
	
	solve2();
	return 0;
}
/*
10011
ans=8


111111
ans=0
000000
ans=0

100
ans=0+1+1

1100
ans=3+2

11110
ans=4 

*/

G: 线段树模板,区间乘积

#include<bits/stdc++.h>

using namespace std;
typedef long long LL;
#define ls u<<1
#define rs u<<1|1
#define fi first
#define se second
int const N=2e5+7,M=2e6+7;

int n,m;
int st[N],top;
LL tot=(1LL)<<32;
//计算后缀乘积 

struct Node{
	int l,r;
	LL mul;
}tr[N<<2]; 


void pushup(Node &p,Node l,Node r){
	if(l.mul==0||r.mul==0){	//注意优先级 
		p.mul=0; 
	}
	else if(l.mul==-1||r.mul==-1){
		p.mul=-1;
	}else{
		long double t=1.0*l.mul*r.mul; //防止溢出 
		if(t>=tot) p.mul=-1;
		else p.mul=t;
	}
}
void pushup(int u){
	pushup(tr[u],tr[ls],tr[rs]);
}
void build(int u,int l,int r){
	tr[u]={l,r,1};
	if(l==r) return;
	int mid=(l+r)>>1;
	build(ls,l,mid);
	build(rs,mid+1,r);
	pushup(u); 
}

void modify(int u,int p,LL v){
	if(tr[u].l==tr[u].r) tr[u].mul=v;
	else{
		int mid=(tr[u].l+tr[u].r)>>1;
		if(mid>=p) modify(ls,p,v);
		else modify(rs,p,v);
		pushup(u);
	} 
}

Node query(int u,int x,int y){
	if(x<=tr[u].l&&tr[u].r<=y) return tr[u];
	int mid=(tr[u].l+tr[u].r)>>1;
	if(mid<x) return query(rs,x,y);
	if(y<=mid) return query(ls,x,y);
	Node res; pushup(res,query(ls,x,y),query(rs,x,y));
	return res;
}

void solve2(){ //线段树维护区间乘积 
	build(1,1,m);
	int T=m;
	while(T--){
		int opt,x; scanf("%d",&opt); 
		if(opt==1){
			scanf("%d",&x);
			st[++top]=x;
			modify(1,top,x);	
		} 
		else if(opt==2){
			if(top>=1){
				modify(1,top,1); //设回1避免干扰 
				top--;
			}
			
		}else{
			scanf("%d",&x);
			if(top<x) printf("ERROR\n");
			else{
				LL res=query(1,top-x+1,top).mul; 
				if(res==-1) printf("OVERFLOW\n");
				else printf("%lld\n",res);
			} 
		}
	
	}
}

void solve(){ //q*logn
	LL tot=(1LL)<<32;	//cout<<tot<<endl;
	while(m--){
		int opt,x; scanf("%d",&opt); 
		if(opt==1){
			scanf("%d",&x);
			st[++top]=x;
		} 
		else if(opt==2){
			top--;
		}else{
			scanf("%d",&x);
			if(top<x) printf("ERROR\n");
			else{
				LL res=1;
				int ok=0;
				for(int i=top;i>=top-x+1;i--){
					res=res*st[i];
					if(res>=tot){
						ok=1;
						break;
					}
				}
				if(ok) printf("OVERFLOW\n");
				else printf("%lld\n",res);
			} 
		}
	
	}
}

int main(){
	scanf("%d",&m);
	solve2();
	
	
	return 0;
}
/*
9
1 65536
1 65536
3 2
3 3
2
1 1024
1 2
3 2
3 3

OVERFLOW
ERROR
2048
134217728


12
1 2
1 2
1 2
1 2
3 1
3 2
3 3
3 4
3 5
2
3 3
3 4


给定一个栈,给出若干次如下类型的操作:
1 x: 将 x 加入栈顶。
2: 将栈顶的数弹出(如果栈是空的,则什么都不做)。
3 y: 查询栈内的最顶端 y 个数的乘积。如果大于等于 2
如果栈内不足 x->(y) 个数,输出 ERROR 。


*/

 H:最后一题写不是正解,不贴了qwq

祝大家都是省一

### 关于第十五届蓝桥杯2024 C/C++ A大学软件的信息 #### 比题目概述 根据已有的信息,第十五届蓝桥杯软件C/C++大学A的比题目尚未完全公开。然而,在某些参者的分享中提到,部分试题涉及算法设计与优化[^1]。例如,“合法密码”问题是其中的一道典型考题,其核心在于字符串处理和合法性验证逻辑的设计[^2]。 #### 时间复杂度的要求 对于一些具体问题,如图论相关的内容,时间效率成为评判标准之一。有记录显示,针对特定类型的输入数据结构(比如边的关系),即使采用较为基础的双重循环实现方法,也能满足竞设定的时间限制——通常为3秒以内完成运算[^3]。 #### 参加者的学习计划建议 为了更好地备战此类事,一位昵称为“牛友”的选手提出了自己的学习规划:利用假期集中精力复习数学基础知识,并通过参与各类线上编程挑战来积累实战经验,目标是从当前学科成功转换至计算机科学领域继续深造。 ```cpp // 示例代码片段展示如何判断简单条件下的合法密码 bool isValidPassword(const std::string& password){ bool hasUpper = false; bool hasLower = false; bool hasDigit = false; if(password.length() < 8 || password.length() > 16) return false; for(char c : password){ if(isupper(c)) hasUpper=true; else if(islower(c)) hasLower=true; else if(isdigit(c)) hasDigit=true; // 假设不允许特殊字符作为简化版规则的一部分 if(!isalnum(c)) return false; } return (hasUpper && hasLower && hasDigit); } ``` 上述函数仅为示意性质,实际比中可能需要考虑更复杂的约束条件以及边界情况测试。 #### 总结 综上所述,参加蓝桥杯这样的高水平程序设计大赛不仅考验选手的技术功底,还需要合理安排训练周期并不断调整策略适应新变化。希望每位热爱编码的人都能在这一过程中收获成长!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值