蓝桥杯b组

文章列举了蓝桥杯编程竞赛中涉及的多种算法问题,包括求和公式、异或选择、青蛙过河的二分查找解法、重新排序的差分与排序策略,以及多路归并和状态压缩DP在解决复杂问题中的应用。此外,还涵盖了进制转换、子矩阵统计等题目,展示了程序设计中的常见技术和策略。
摘要由CSDN通过智能技术生成

注意事项

  • 数据范围long long int
  • using namespace std;
  • 要有输入

十三届蓝桥杯a

求和——公式

选两个数相乘,运用公式:
( ( a 1 + a 2 + a 3 + . . . + a n ) 2 − ( a 1 2 + a 2 2 + a 3 2 + . . . + a n 2 ) ) / 2 ((a_1+a_2+a_3+...+a_n)^2-(a_1^2+a_2^2+a_3^2+...+a_n^2))/2 ((a1+a2+a3+...+an)2(a12+a22+a32+...+an2))/2

选数异或

暴力

//  a1 @a2=x   a1=a2@x
#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;
const int N=1e5+10;
int a[N],b[N];
int n,m,x;
int main()
{
    cin>>n>>m>>x;
    for(int i=1;i<=n;i++)
      cin>>a[i];
     for(int i=1;i<=n;i++)
       b[i]=a[i]^x;
    while(m--)
    {
        int l,r;
        bool flag=0;
        cin>>l>>r;
        
        for(int i=l;i<=r;i++)
         { for(int j=l;j<=r;j++)
            if(a[j]==b[i])
              {
                  flag=1;
                  break;
              }
             if(flag==1)  break;
         }
         
         if(flag)  puts("yes");
         else puts("no");
    }
}

青蛙过河——二分

一组数据没有过

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int n,x;
const int N=1e5+10;
int a[N];
bool check(int mid)
{
   
   long long int sum=0;
    for(int i=0,j=0;i<=n;i++)
    {
        sum+=a[i];
        while(i-j==mid)
        {
            if(sum<(long long int)2*x)  return false;
            else 
            {
                j++;
                sum-=a[j];
            }
        }
    }
    return true;
}
int main()
{
    cin>>n>>x;
    for(int i=1;i<n;i++)  
    {
        cin>>a[i];
    }
    int l=1,r=n;
    while(l<r)
    {
        int mid=l+r>>1;
        if(check(mid))  //true :跳的小一点
            r=mid;
        else  l=mid+1;
    }
    cout<<l<<endl;
}

十三届蓝桥杯c

重新排序——差分,排序不等式

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m;
const int N=1e5+10;
int a[N],c[N];
typedef long long LL;
LL res1,res2;
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
     scanf("%d",&a[i]);
    cin>>m;
   while(m--)
    {
       int l,r;
       cin>>l>>r;
       c[l]++,c[r+1]--;
    }
    for(int i=1;i<=n;i++)  c[i]+=c[i-1];
    
    for(int i=1;i<=n;i++)
      res1+=(LL)c[i]*a[i];                 //转化为LL
     sort(a+1,a+n+1,cmp);
     sort(c+1,c+n+1,cmp);
  //   for(int i=1;i<=n;i++)  cout<<a[i]<<" ";
   //  cout<<endl;
    for(int i=1;i<=n;i++)
      res2+=(LL)c[i]*a[i];
      cout<<res2-res1<<endl;
     //printf("%d",res2-res1);
}

技能提升——多路归并

鱼塘钓鱼

有 N
个鱼塘排成一排,每个鱼塘中有一定数量的鱼,例如:N=5
时,如下表:
鱼塘编号 1 2 3 4 5
第1分钟能钓到的鱼的数量(1…1000) 10 14 20 16 9
每钓鱼1分钟钓鱼数的减少量(1…100) 2 4 6 5 3
当前鱼塘到下一个相邻鱼塘需要的时间(单位:分钟) 3 5 4 4
即:在第 1
个鱼塘中钓鱼第 1
分钟内可钓到 10
条鱼,第 2
分钟内只能钓到 8
条鱼,……,第 5
分钟以后再也钓不到鱼了。

从第 1 个鱼塘到第 2 个鱼塘需要 3 分钟,从第 2 个鱼塘到第 3个鱼塘需要 5分钟,……
给出一个截止时间 T,设计一个钓鱼方案,从第 1个鱼塘出发,希望能钓到最多的鱼。
假设能钓到鱼的数量仅和已钓鱼的次数有关,且每次钓鱼的时间都是整数分钟。
输入格式
共 5 行,分别表示:
第 1 行为 N;
第 2 行为第 1 分钟各个鱼塘能钓到的鱼的数量,每个数据之间用一空格隔开;
第 3 行为每过 1 分钟各个鱼塘钓鱼数的减少量,每个数据之间用一空格隔开;
第 4 行为当前鱼塘到下一个相邻鱼塘需要的时间;
第 5 行为截止时间 T。
输出格式
一个整数(不超过231−1),表示你的方案能钓到的最多的鱼。
数据范围
1≤N≤100,
1≤T≤1000
输入样例:
5
10 14 20 16 9
2 4 6 5 3
3 5 4 4
14
输出样例:
76

#include<iostream>
#include<iostream>
#include<cstring>

using namespace std;
const int N=110;
int a[N],d[N],l[N],spend[N];
//在第k个鱼塘吊的数量
 int get (int k)
 {
 	return max(0,a[k]-d[k]*spend[k]);
 }
int work(int n,int T)
{
	int res=0;
	memset(spend,0,sizeof spend);
	for(int i=0;i<T;i++)
	{
		int t=1;
		for(int j=1;j<=n;j++ )
		  if(get(j)>get(t)) 
		    t=j;
		res+=get(t);
		spend[t]++;
	}
	return res;
}
int main()
{
	int n,T;
	cin>>n;
	for(int i=1;i<=n;i++)  cin>>a[i];  //第一分钟各个鱼塘钓到鱼的数量 
	for(int i=1;i<=n;i++)  cin>>d[i]; //每过一分钟鱼塘钓鱼数的减少量 
    for(int i=2;i<=n;i++)
    {
    	cin>>l[i];    //当前鱼塘到下一个相邻鱼塘的时间 
		l[i]+=l[i-1];
	}
	cin>>T;        //截止时间 
	
	int res=0;
	for(int i=1;i<=n;i++)     //枚举最终走到哪个鱼塘 
	  res=max(res,work(i,T-l[i]));
	  
	 cout<<res; 
 } 

十三届蓝桥杯b

填空

九进制转十进制

顺子日期

程序设计

刷题统计

修剪灌木

X进制减法*

进制规定了数字在数位上逢几进一。X进制是一种很神奇的进制,因为其每一数位的进制并不固定!
例如说某种 X 进制数,最低数位为二进制,第二数位为十进制,第三数位为八进制,则 X 进制数 321 转换为十进制数为 65。

现在有两个 X 进制表示的整数 A 和 B,但是其具体每一数位的进制还不确定,只知道 A 和 B 是同一进制规则,且每一数位最高为 N 进制,最低为二进制。请你算出 A−B的结果最小可能是多少。
请注意,你需要保证 A 和 B 在 X 进制下都是合法的,即每一数位上的数字要小于其进制。
输入格式
第一行一个正整数 N,含义如题面所述。
第二行一个正整数 Ma,表示 X 进制数 A 的位数。
第三行 Ma 个用空格分开的整数,表示 X 进制数 A 按从高位到低位顺序各个数位上的数字在十进制下的表示。
第四行一个正整数 Mb,表示 X 进制数 B 的位数。
第五行 Mb 个用空格分开的整数,表示 X 进制数 B 按从高位到低位顺序各个数位上的数字在十进制下的表示。
请注意,输入中的所有数字都是十进制的。
输出格式
输出一行一个整数,表示 X 进制数 A−B 的结果的最小可能值转换为十进制后再模 1000000007 的结果。
数据范围
对于 30% 的数据,N≤10;Ma,Mb≤8,对于 100% 的数据,2≤N≤1000;1≤Ma,Mb≤100000;A≥B。
输入样例:

11
3
10 4 0
3
1 2 0

输出样例:

94

样例解释
当进制为:最低位 2
进制,第二数位 5
进制,第三数位 11
进制时,减法得到的差最小。
此时 A 在十进制下是 108,B 在十进制下是 14,差值是 94。

统计子矩阵——前缀和,双指针

题目描述

给定一个 N×M 的矩阵 A,请你统计有多少个子矩阵 (最小 1×11×1,最大 N×M) 满足子矩阵中所有数的和不超过给定的整数 K?

输入格式

第一行包含三个整数 N,M和 K。

之后 N 行每行包含 M个整数,代表矩阵 A。

输出格式

一个整数代表答案。

数据范围

对于 30%30% 的数据,N,M≤20,
对于 70%70% 的数据,N,M≤100,
对于 100%100% 的数据,1≤N,M≤500;0≤Aij≤1000;1≤K≤2.5×10^8。

输入样例:

3 4 10
1 2 3 4
5 6 7 8
9 10 11 12

输出样例:

19

样例解释

满足条件的子矩阵一共有 1919,包含:

  • 大小为 1×11×1 的有 1010 个。
  • 大小为 1×21×2 的有 33 个。
  • 大小为 1×31×3 的有 22 个。
  • 大小为 1×41×4 的有 11 个。
  • 大小为 2×12×1 的有 33 个。

前缀和(超时)

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=510;
int n,m,k;
int a[N][N],s[N][N];

int main()
{
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	  cin>>a[i][j];
	  
	for(int i=1;i<=n;i++)
	  for(int j=1;j<=m;j++)
	    s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
	    
	    int res=0;
	for(int i=1;i<=n;i++)
	 for(int j=1;j<=m;j++)
	  for(int p=i;p<=n;p++)    //注意 
	     for(int q=j;q<=m;q++)
	     {
	     	int x=s[p][q]-s[p][j-1]-s[i-1][q]+s[i-1][j-1];
	     	if(x<=k) 
			 {
			 res++;
			  } 
		 }
		 cout<<res<<endl;
}

前缀和加双指针

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=510;
int n,m,k;
int a[N][N],s[N][N];

int main()
{
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	  cin>>a[i][j];
	  
	for(int i=1;i<=n;i++)
	  for(int j=1;j<=m;j++)
	    s[i][j]=s[i-1][j]+a[i][j];
	    
	   long long  int res=0;  //数据范围
	   
	   for(int i=1;i<=n;i++)
	     for(int j=i;j<=n;j++)
	        for(int l=1,r=1,sum=0;r<=m;r++)
	       {
	         sum+=s[j][r]-s[i-1][r];
	         
	         while(sum>k)
	         {
	             sum-=s[j][l]-s[i-1][l];
	             l++;
	             
	         }
	          res+=r-l+1;
	       }
	    
		 cout<<res<<endl;
		 return 0;
}

积木画——状态压缩DP

扫雷

李白打酒加强版

砍竹子

十二届蓝桥杯b

填空题

空间

卡片

50%

#include <iostream>
using namespace std;
int n;
bool check(int x)
{
  int res=0;
  for(int i=1;i<=x;i++)
   res+=i;
   if(res>=n)  return true;
   return false;
}
int main()
{
  // 请在此输入您的代码
  
  cin>>n;
  int l=1,r=n;

  while(l<r)
  {
    int mid=l+r>>1;
    if(check(mid))   //大
      r=mid;
      else l=mid+1;
  }
  cout<<l<<endl;
  return 0;
}

100%

#include<iostream>
#include<cstring>
using namespace std;

int main()
{
    int n;
    cin>>n;
    int res=1;
    for(int i=2;;i++)
      {
        res+=i;
        if(res>=n) 
        {
          cout<<i;
          break;
        } 
      }
      return 0;
}

直线

货物摆放

路径dijkstra

答案10266837

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=3000;
int g[N][N],dist[N]; 
bool st[N];
int gcd(int a,int b)
{
	return b?gcd(b,a%b):a;
}
int lcm(int a,int b)   //最小公倍数 
{
	int x=a*b;
	return x/gcd(a,b);
}
int dijkstra()
{
	memset(dist,0x3f,sizeof dist);
	  dist[1]=0;
	for(int i=0;i<2021;i++)
	{
		int t=-1;
		for(int j=1;j<=2021;j++)
		  if(!st[j]&&(t==-1||dist[j]<dist[t]))
		      t=j;
		st[t]=true;
		for(int j=1;j<=2021;j++)
		  dist[j]=min(dist[j],dist[t]+g[t][j]);
	}
	if(dist[2021]==0x3f3f3f3f)  return -1;
	return dist[2021];
}
int main()
{
	memset(g,0x3f,sizeof g);
	
	for(int i=1;i<=2021;i++)
	{
		for(int j=i+1;j<=i+21;j++)
		{
			 g[i][j]=lcm(i,j);
			 g[j][i]=lcm(i,j);
		}
	}
	int t=dijkstra();
	cout<<t;
	
}

程序设计

时间显示

砝码称重

杨辉三角形

双向排序

括号序列

模拟

最大连通——DFS

#include <iostream>
#include<algorithm>
#include<queue>
#define x first
#define y second
using namespace std;
typedef pair<int,int>PII;
int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
char g[30][60],a[30][60];
int bfs(int x,int y)
{
  queue<PII> q;
  q.push({x,y});
  g[x][y]='0';      //不要漏了 
  int res=1;
  while(q.size())
  {
    PII t=q.front();
    q.pop();
   for(int i=0;i<4;i++)
   {
    int sx=t.x+dx[i],sy=t.y+dy[i];
    if(sx<0||sy<0||sx>=30||sy>=60||g[sx][sy]=='0')  continue;
     g[sx][sy]='0';
     q.push({sx,sy});
     res++;           //注意
   }
  }
  return res;
}
int main()
{
  for(int i=0;i<30;i++)  cin>>a[i];
int res=0;
  for(int i=0;i<30;i++)
    for(int j=0;j<60;j++)
    {
       memcpy(g,a,sizeof a);
       if(a[i][j]=='1')
       res=max(res,bfs(i,j));
    }
cout<<res;
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
蓝桥杯B真题嵌入式考察了关于嵌入式系统的相关知识与技能。嵌入式系统是指嵌入到其他设备或系统中的计算机系统,通常用于控制和执行特定的功能。嵌入式系统广泛应用于家电、汽车、医疗设备等各个领域。 该题目要求参赛者设计一个简单的温度采集系统,并将采集到的温度数据通过串口发送给电脑进行显示。这个问题需要我们准备一个温度传感器模块、单片机、串口通信模块、以及电脑上的相应应用程序。 首先,我们需要将温度传感器与单片机相连接并进行编程,使得单片机可以读取到传感器的温度数值。在编程时,需要注意选择合适的编程语言,如C语言或者汇编语言,并熟悉单片机的编程接口与指令集。 接下来,我们需要通过串口通信模块将采集到的温度数据发送给电脑。串口通信是一种常用的嵌入式系统与外部设备之间的通信方式,通常使用UART协议。在单片机编程中,需要设置合适的串口参数,如波特率和数据位数等。 最后,我们需要在电脑上编写相应的应用程序,来接收并显示串口传输过来的温度数据。在编写应用程序时,可以使用编程语言如Python或C#来实现串口的读取与显示工作。 总结来说,蓝桥杯B真题嵌入式主要考察了嵌入式系统的设计与编程能力,包括传感器与单片机的接口设计、单片机的编程以及串口通信与应用程序的开发等方面的知识与技能。通过解答这个问题,参赛者可以加深对嵌入式系统的理解与实践经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值