2024第15届蓝桥杯C/C++大学生A组省赛个人刷题记录

试题A:艺术与篮球(AC)

题解代码:(答案为3228)

#include<bits/stdc++.h>
using namespace std;

int cnt[10]={13,1,2,3,5,4,4,2,2,2}; 

int leapyear(int year){
	if((year%400==0)||(year%4==0&&year%100!=0)){
		return 1;
	}
	else return 0;
}

int maxday(int year,int month){
	if(month==1||month==3||month==5||month==7||month==8||month==10||month==12) return 31;
	else if(month==4||month==6||month==9||month==11) return 30;
	else if(leapyear(year)) return 29;
	else return 28;
}

int main(){
    int basketball=0;
    int year=2000,month=1,day=1;
    int sum=0;
    while(1){
		sum+=cnt[year%10]+cnt[year/10%10]+cnt[year/100%10]+cnt[year/1000%10];  //年 
		sum+=cnt[month%10]+cnt[month/10%10];  //月
		sum+=cnt[day%10]+cnt[day/10%10];  //日
		if(sum>50){
			basketball++;
		}
		if(year==2024&&month==4&&day==13) break;
		else{
			if(day<maxday(year,month)){
				day++;
			}
			else if(month!=12){
				month++;
				day=1;
			}
			else{
				year++;
				month=1;
				day=1;
			}
		}
		sum=0;
	}
	cout<<basketball;
	return 0; 
}

试题B:五子棋对弈(AC)

题解代码:(答案为3126376)

#include<bits/stdc++.h>
using namespace std;
int a[6][6];
int ans=0;
void dfs(int n1,int n2,int id,int c)  //白棋个数,黑棋个数,当前格子序号,当前格子颜色
{
   if(n1>13||n2>12||id>=25) return;
   int x=id/5,y=id%5;
   a[x][y]=c;
   if(y==4){  //检查当前行 
   	 int flag=0;
   	 for(int i=1;i<=4;i++){
   		if(a[x][i]!=a[x][0]) flag=1;
	 }
	 if(flag==0) return;
   }
   if(x==4){  //检查当前列 
   	 int flag=0;
   	 for(int i=1;i<=4;i++){
   		if(a[i][y]!=a[0][y]) flag=1;
	 }
	 if(flag==0) return;
   }
   if(id==20){  //检查右上到左下对角线 
   	 int flag=0;
   	 for(int i=1;i<=4;i++){
   		if(a[i][4-i]!=a[0][4]) flag=1;
	 }
	 if(flag==0) return;
   }
   if(id==24){  //检查左上到右下对角线  
   	 int flag=0;
   	 for(int i=1;i<=4;i++){
   		if(a[i][i]!=a[0][0]) flag=1;
	 }
	 if(flag==0) return;
   }
   if(id==24){  //顺利通过以上检查并且棋盘下满时,平局数加一 
   	 ans++;
   	 return;
   }
   dfs(n1+1,n2,id+1,1);  //下一个格子放白棋
   dfs(n1,n2+1,id+1,2);  //下一个格子放黑棋
}
int main()
{
	dfs(1,0,0,1);  //枚举第一个格子放白棋的所有情况
	dfs(0,1,0,2);  //枚举第一个格子放黑棋的所有情况
	cout<<ans;
	return 0;
}

试题C:训练士兵(AC)

题解代码:

#include <bits/stdc++.h>
using namespace std;

struct Soldier{
	long long p;
	int c;
}soldier[100002];

bool cmp(Soldier a,Soldier b){
	if(a.c==b.c) return (a.p<b.p);
	return a.c<b.c;
}

long long presum[100002];//前缀和数组,存前i个士兵均单独训练的价格 

int main() {
    long long n,s;
    cin>>n>>s;
    for(long long i=1;i<=n;i++){
    	cin>>soldier[i].p>>soldier[i].c;
	}
	sort(soldier+1,soldier+n+1,cmp);
	presum[0]=0;
	for(long long i=1;i<=n;i++){
		presum[i]=presum[i-1]+soldier[i].p;
	}
    long long i=1;
	while(1){
		if(s>(presum[n]-presum[i-1])) break;
		i++;
	}
	long long result=0;
	result+=s*soldier[i-1].c;
	for(long long j=i;j<=n;j++){
		result+=soldier[j].p*(soldier[j].c-soldier[i-1].c);
	}
	cout<<result;
    return 0;
}

试题D:团建(AC)

题解代码:

#include <bits/stdc++.h>
using namespace std;

const int maxsize=2e5+10;
int n, m;
int c[maxsize], d[maxsize];
vector<int> neighbor1[maxsize], neighbor2[maxsize];

int search(int v,int u,int fa_v,int fa_u){
	int ans=0;
	map<int,int> son_v;
	for(auto x:neighbor1[v]){
	   if(x!=fa_v){
	      son_v[c[x]]=x;
	   }
	}
	for(auto x:neighbor2[u]){
	   if(x!=fa_u){
		  if(son_v.count(d[x])){
		     ans=max(ans,search(son_v[d[x]],x, v, u));
		  }
	   }
	}
	
	return ans+1;
}

int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>c[i];
	for(int i=1;i<=m;i++) cin>>d[i];
	int u,v;
	for(int i=1;i<n;i++){
	   cin>>u>>v;
       neighbor1[u].push_back(v);
	   neighbor1[v].push_back(u);
	}
	for(int i=1;i<m;i++){
	   cin>>u>>v;
	   neighbor2[u].push_back(v);
	   neighbor2[v].push_back(u);
	}
	int ans=0;
	if(c[1]==d[1]){
	   ans=search(1,1,0,0);
	}
	cout<<ans<<endl;
	return 0;
}

 试题E:成绩统计(AC)

题解代码:

#include<bits/stdc++.h>
#define N 100005
using namespace std;

int n,k,a[N]; 
double t,num[N],sq_pre[N],pre[N];

bool cmp(double x,double y){
	return x<y;
}

bool testOK(int x){
	for(int i=1;i<=x;i++)
		num[i]=a[i];
	sort(num+1,num+x+1,cmp);
	for(int i=1;i<=x;i++){
		pre[i]=pre[i-1]+num[i];
		sq_pre[i]=sq_pre[i-1]+num[i]*num[i];
	}
	for(int begin=1;begin+k-1<=x;begin++)
		if(sq_pre[begin+k-1]-sq_pre[begin-1]-(pre[begin+k-1]-pre[begin-1])*(pre[begin+k-1]-pre[begin-1])/k<k*(double)t)
			return true;
	return false;
}

int main(){
	cin>>n>>k>>t;
	if(k>n){
		cout<<"-1";
		return 0;
	}
	for(int i=1;i<=n;i++)
		cin>>a[i];
	int left=k,right=n,mid;
	while(true){
		if(left==right){
			cout<<(testOK(left)?left:-1);
			return 0;
		}
		mid=(left+right)/2;
		if(testOK(mid))
			right=mid;
		else
			left=mid+1;
	}
}

试题F:因数计数(36分)                                         

题解代码:

                                                                                                                                                                                                                                                                                                                                        \\\\\\\

试题G:零食采购(27分)

题解代码:

#include <bits/stdc++.h>
using namespace std;
 
vector<vector<int>> adj;  // 邻接表表示树
vector<int> c;            // 每个星球的零食种类
vector<int> path;         // 存储从起点到终点的路径
bool found = false;       // 标记是否找到路径
 
// DFS查找从u到v的路径
void dfs(int u, int v, vector<int>& currentPath, vector<bool>& visited) {
    visited[u] = true;
    currentPath.push_back(u);
 
    if (u == v) {
        path = currentPath;  // 找到路径
        found = true;
        return;
    }
 
    for (int neighbor : adj[u]) {
        if (!visited[neighbor]) {
            dfs(neighbor, v, currentPath, visited);
            if (found) return;  // 如果找到路径,直接返回
        }
    }
    currentPath.pop_back();  // 回溯。由于是树,vis可以不用回溯
}
 
int main() {
    int n, q;
    cin >> n >> q;
    adj.resize(n + 1);
    c.resize(n + 1);
 
    // 输入每个星球的零食种类
    for (int i = 1; i <= n; i++) {
        cin >> c[i];
    }
 
    // 输入n-1条边,构建树
    for (int i = 1; i < n; i++) {
        int u, v;
        cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
 
    // 处理每个查询
    for (int i = 0; i < q; i++) {
        int s, t;
        cin >> s >> t;
 
        // 初始化
        path.clear();
        found = false;
        vector<bool> visited(n + 1, false);
        vector<int> currentPath;
 
        // 查找从s到t的路径
        dfs(s, t, currentPath, visited);
 
        // 统计路径上的零食种类
        set<int> kinds;
        for (int node : path) {
            kinds.insert(c[node]);
        }
 
        // 输出结果
        cout << kinds.size() << endl;
    }
 
    return 0;
}
2023年的第十四蓝桥杯 C/C++ 大学生 A 是一个非常重要且具有挑战性的比。作为蓝桥杯系列事的一部分,这个比吸引了全国各地的大学生参与,旨在促进青年学生计算机编程技术的提高,培养他们的创新能力和团队协作精神。 参者需要通过线上报名,在规定的时间内上传自己的比作品。比设置了一系列难度逐渐增加的编程题目,要求选手运用C/C++语言进行编写和实现。这些题目可能涉及算法设计、数据结构、编程基础等方面的知识,考察参者的编码能力、解决问题的能力以及在压力下的应变能力。 在比中,选手不仅需要具备扎实的编程技术,还需要在有限的时间内迅速分析问题、设计解决方案,并通过编程实现。因此,参者需要具备良好的逻辑思维能力、数学基础和编程实践经验。 在中取得好成绩的选手将有机会晋级到全国,进一步与全国各地的顶尖选手一较高下,争夺更好的名次和更多的奖品。 参加蓝桥杯 C/C++ 大学生不仅是一次锻炼和展示自己编程能力的机会,还能结识更多志同道合的同学和业界精英,获得丰厚的奖金和荣誉。同时,参经历对于大学生未来的学习和职业发展也具有积极的影响。 总之,2023年第十四蓝桥杯 C/C++ 大学生 A 是一个具有挑战性的比,参者需要具备扎实的编程技术和解决问题的能力。通过参与比,学生可以提升自己的编程能力,拓宽视野,展示个人才华,并为未来的学习和就业打下坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值