第十四届蓝桥杯C++A组(A/B/C/D/E/H)

本文通过五个C++代码示例讲解了幸运数的暴力求解、深度/广度优先搜索、平方差问题、字符串反转及颜色平衡树构建,展示了IT技术中实际问题的解决方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A.幸运数

在这里插入图片描述

/*纯暴力*/
#include <bits/stdc++.h>

using namespace std;

void solve()
{
	int sum = 0;
	for(int i = 1; i <= 100000000; i ++ )
	{
		int n = i;
		int a[11];
		int j = 1;
		for(; n != 0; j ++ )
		{
			a[j] = n % 10;
			n = n / 10;
		}
		j --;
		if(j % 2 == 0)
		{
			int sum1 = 0, sum2 = 0;
			for(int u = 1; u <= j / 2; u ++ )
			{
				sum1 = sum1 + a[u];
				sum2 = sum2 + a[j/2 + u];
			}
			if(sum1 == sum2) sum ++ ;
		}
	}
	cout << sum;
}

int main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	solve();
	cout << ans << endl;
	return 0;
}
/*dfs搜索*/
#include <bits/stdc++.h>

using namespace std;

int ans;

void dfs(int x, int l, int r)
{
  if(l != 0 && l == r) ans ++ ; //非0且相等才可以,卡掉刚开始进入时的dfs(0, 0, 0)
  if(x == 4) return; //递归出口
  for(int i = 0; i <= 9; i ++ )
  {
    if(l == 0 && i == 0) continue; //从高位开始枚举,所以第一次l不可以是0,i也不是0
      for(int j = 0; j <= 9; j ++ )
        dfs(x + 1, l + i, r + j);
  }
}

int main()
{
  ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	dfs(0,0,0);
	cout << ans << endl;
  return 0;
}

B.有奖问答

在这里插入图片描述

#include<bits/stdc++.h>

using namespace std;

int ans = 0;

void bfs(int step, int score)
{
	if(score == 70) ans ++ ; //达到70分可以停止记为一次成功
	if(score == 100 || step == 30) return; //递归出口:满分立即停止,满30次立即停止

	bfs(step + 1, score + 10); //答对
	bfs(step + 1, 0); //答错
}

int main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	bfs(0, 0);
	cout << ans << endl;
	return 0;
}

C.平方差

在这里插入图片描述

#include<bits/stdc++.h>

using namespace std;

/*****思路:*****/

/*
y方 - z方 = (y - z)(y + z)
y-z和y+z始终是同奇偶的
奇*奇 = 奇
偶*偶 = 偶(且该数必然是4的倍数)
*/

/*
x方 - (x-1)方 = 2x - 1则所有奇数满足拆分
x方 - (x-2)方 = 4x - 4则所有4的倍数满足拆分
*/

/*
所以如果要查找1~n中满足的x则***return (x + 1)/2 + x/4***即可
*/

int calc(int x)
{
  //(x + 1)/2是奇数乘以奇数部分,x/4是偶数乘以偶数部分
  return (x + 1)/2 + x/4;
}

int main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
  int l,r;
  cin >> l >> r;
  cout << calc(r) - calc(l - 1) << endl;
	return 0;
}

D.更小的数

在这里插入图片描述

#include<bits/stdc++.h>

using namespace std;

const int MAX = 5020;
int dp[MAX][MAX]; //dp[len][i]表示从i开始长度为len的子串反转是否可以满足,满足为1,不满足为0
int ans = 0;

//dp动态规划
void solve()
{
	string s;
	cin >> s;
	int n = s.length();
  
	for(int len = 2; len <= n; len ++ ) //遍历每种长度
		for(int l = 0; l + len - 1 < n; l ++ ) //遍历每个起点
		{
      //每次比较最边缘两个,如果不满足则各向中间靠一位再比较(可以直接使用dp)
			if(s[l] > s[l + len - 1]) dp[l][l + len - 1] = 1;
			else if(s[l] == s[l + len - 1]) dp[l][l + len - 1] = dp[l + 1][l + len - 2];

			ans += dp[l][l + len - 1]; //累加答案
		}
	
	cout << ans << endl;
}

int main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	solve();
	return 0;
}

E.颜色平衡树

在这里插入图片描述

#include<bits/stdc++.h>

using namespace std;

const int N = 2e5 + 5;
int n, ans;
map<int, int>col[N],num[N]; //col[N]每个颜色多少数量,num[N]每个数量有几组
vector<int> e[N];

void dfs(int u) //从上到下,u为此时树的根节点
{
  for(auto &v:e[u]) //所有遍历一遍,自顶向下再自底向上
  {
    dfs(v);
    //合并两树
    if(col[u].size() < col[v].size()) //u是保持的,v要更新,所以让u更大耗时更少
    {
      col[u].swap(col[v]);
      num[u].swap(num[u]);
    }
    for(auto it = col[v].begin();it != col[v].end(); it ++ )
    {
      int v_col = it->first, v_num = it->second;
      if(col[u].count(v_col)) //u树中含有v中该颜色,则要更新num颜色数量组
      {
        int u_num = col[u][v_col];
        num[u][u_num] -- ;
        if(num[u][u_num] == 0) num[u].erase(u_num);
        num[u][u_num + v_num] ++ ;
      }
      else num[u][v_num] ++ ; //u树不含有则直接添加
      col[u][v_col] += v_num; //更新col
    }
    map<int, int> tmp1, tmp2; //释放v
    col[v].swap(tmp1);
    num[v].swap(tmp2);
  }
  if(num[u].size() == 1) ans ++ ; //最大最小都是在一个num上则是满足的
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
  cin >> n;
  for(int u = 1; u <= n; u ++ )
  {
    int c, fa;
    cin >> c >> fa;
    e[fa].push_back(u); //父节点向子节点连一条边
    col[u][c] ++ ; //此时u节点树中,只有c一种颜色,且只要一个,first是颜色,second是数量
    num[u][1] ++ ; //此时u节点树中,只有1种颜色的,且其只有一个,first是数量,second是该数量有几套颜色
  }
  dfs(1);
  cout << ans;
    return 0;
}

H.异或和之和

在这里插入图片描述

#include<bits/stdc++.h>

using namespace std;

/*****思路:*****/

/*
从前往后遍历
每次遍历该值的所有前缀异或和的每一位的累加值
可以使用i - cnt[j]来表示
最后按位累加即可
*/

typedef long long LL;
int cnt[21];//cnt[i]表示第i位为1的可能情况有多少种

void solve()
{
	int n;
  cin >> n;
  LL ans = 0;
  for(int i = 1; i <= n; i ++ ) //从前往后遍历每一个数
  {
    int a;
    cin >> a;
    for(int j = 0; j <= 20; j ++ ) //遍历每一位
    {
      if((1 << j) & a) cnt[j] = i - cnt[j]; //只有该位是1的时候才会有此异或变化
      ans += 1ll * (1 << j) * cnt[j];
    }
  }
  cout << ans;
  return;
}

int main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	solve();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值