蓝桥杯B组C/C++前五道题(作业)

A.日期统计

小蓝现在有一个长度为100 的数组,数组中的每个元素的值都在0 到9 的范围之内,现在他想要从这个数组中寻找一些满足以下条件的子序列,对于相同的日期你只需要统计一次即可。

暴力走一遍就可以了,就是麻烦了一点,毕竟新手。

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

int dayx[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int main()
{
 int p[42];
 int res,ant=1,flog,flog1,flog2,flog4,flog3;
 for(int i=1;i<=41;i++){
  cin>>p[i];
 }
 for(int i=1;i<=12;i++){
  for(int j=1;j<=dayx[i];j++){
   ant=1;
   flog1=flog2=flog3=flog4=0;
   if(i<10){
    for(int a=ant;a<=41;a++){
     ant=a;
     if(p[a]==0){
      flog4=1;
      break;
     }
    }
   }else{
    for(int a=ant+1;a<=41;a++){
     ant=a;
     if(i/10==p[a]){
      flog4=1;
      break;
     }
    }
   }
   for(int a=ant+1;a<=41;a++){
    ant=a;
    if(i%10==p[a]){
     flog3=1;
     break;
    }
   }
   if(j<10){
    for(int a=ant+1;a<=41;a++){
     ant=a;
     if(p[a]==0){
      flog2=1;
      break;
     }
    }
   }else{
    for(int a=ant+1;a<=41;a++){
     ant=a;
     if(j/10==p[a]){
      flog2=1;
      break;
     }
    }
   }
   for(int a=ant+1;a<=41;a++){
    ant=a;
    if(j%10==p[a]){
     flog1=1;
     break;
    }
   }
   if(flog1&&flog2&&flog3&&flog4&&ant<=41){
    res++;
    cout<<i<<' '<<j<<endl;
   }
  }
 }
 cout<<res<<endl;
 return 0;
}

B.01 串的熵

对于一个长度为 n 的 01 串 S = x1 x2 x3...xn,香农信息熵的定义为 H(S ) = −Σ n 1 p(xi)log2 (p(xi)),其中 p(0), p(1) 表示在这个 01 串中 0 和 1 出现的占比。 比如,对于 S = 100 来说,信息熵 H(S ) = − 1 3 log2 ( 1 3 ) − 2 3 log2( 2 3 ) − 2 3 log2 ( 2 3 ) = 1.3083。对于一个长度为 23333333 的 01 串,如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少,那么这个 01 串中 0 出现了多少次?

需要double确定一下精度,然后带公式进去。

#include<iostream>
#include<cstdio>
#include<bits/stdc++.h>
using namespace std;
int n=23333333;
void check(int i){
	int n=23333333;
	double x=(-1.0)*i/n*log2(1.0*i/n)*i;
	double y=(-1.0)*(n-i)/n*log2(1.0*(n-i)/n)*(n-i);
	if(x+y>=11625907.5798 && x+y<=11625907.5799){
		cout<<i;
		return;
	}
	return ;
}
int main()
{
	for(int i=1;i<=n/2;i++){
		check(i);
	}
	return 0;
}

C.冶炼金属

小蓝有一个神奇的炉子用于将普通金属 O 冶炼成为一种特殊金属 X。这个 炉子有一个称作转换率的属性 V,V 是一个正整数,这意味着消耗 V 个普通金 属 O 恰好可以冶炼出一个特殊金属 X,当普通金属 O 的数目不足 V 时,无法 继续冶炼。 现在给出了 N 条冶炼记录,每条记录中包含两个整数 A 和 B,这表示本次 投入了 A 个普通金属 O,最终冶炼出了 B 个特殊金属 X。每条记录都是独立 的,这意味着上一次没消耗完的普通金属 O 不会累加到下一次的冶炼当中。 根据这 N 条冶炼记录,请你推测出转换率 V 的最小值和最大值分别可能是 多少,题目保证评测数据不存在无解的情况。

思路:因为题目肯定能保证有解,所以每条记录都要找到本记录的最值,然后从满足每条记录的最小值中取最大值,从满足每条记录的最大值中取最小值即可。

#include<bits/stdc++.h>
using namespace std;
int n,a,b,x=-1,y=1e9;
int main(){
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>a>>b;
		x=max(x,a/(b+1)+1); //x为第一条到当前记录能满足最小值的最大值  a/(b+1)+1表示当前记录能满足的最小值 
		y=min(y,a/b);       //y为第一条到当前记录能满足最大值的最小值  a/b 表示当前记录能满足的最大值  
	}
	cout<<x<<" "<<y;
	return 0;
}

D.飞机降落

N 架飞机准备降落到某个只有一条跑道的机场。其中第 i 架飞机在 Ti 时刻 到达机场上空,到达时它的剩余油料还可以继续盘旋 Di 个单位时间,即它最早 可以于 Ti 时刻开始降落,最晚可以于 Ti + Di 时刻开始降落。降落过程需要 Li 个单位时间。 一架飞机降落完毕时,另一架飞机可以立即在同一时刻开始降落,但是不 能在前一架飞机完成降落前开始降落。 请你判断 N 架飞机是否可以全部安全降落。

思路 DFS全排序,把所有的降落顺序都走一遍,全部降落成功说明有这一情况。

#include <bits/stdc++.h>

using namespace std;

const int N = 10;
bool s[N];
int n;

struct plane
{
    int t, d, l; //定义结构体 
}p[N];

bool dfs(int u, int last)
{
    if(u == n) return true; 
	//如果走到这步,说明该选择的排序都可以满足所以飞机,直接返回true;如果有一项不满足是走不到这里的 
    
    for(int i = 0; i < n; i ++) //全排序循环,这里指把所有降落的飞机的顺序全部排一遍; 
    {
        int t = p[i].t, d = p[i].d, l = p[i].l;
        if(!s[i] && t + d >= last) //如果当前满足降落时间大于所给的降落时间,说明可以降落 
        {
            s[i] = true; //当前排序说明已经走过了 
            if(dfs(u + 1, max(t, last) + l)) return true;
            //u+1开始下一辆;max(t,last)当前降落时间和上次降落时间取个最大值,再加上当前所需的降落时间;
			//如果不满足下一架飞机,则直接false;准备恢复现场; 然后return false; 
            s[i] = false; //恢复现场 
        }
    }
    
    return false; 
}
int main()
{
    int T;
    cin >> T;
    while(T --)
    {
        cin >> n;
        memset(st, false, sizeof st);
        for(int i = 0; i < n ; i ++)
        {
            int t, d, l;
            scanf("%d%d%d", &t, &d, &l);
            p[i] = { t, d, l}; //给结构体赋值 
        }
        if(dfs(0, 0)) puts("YES"); //满足返回YES,否则NO; 
        else puts("NO");
    }
    
    
    return 0;
}

E: 接龙数列

对于一个长度为 K 的整数数列:A1, A2, . . . , AK,我们称之为接龙数列当且 仅当 Ai 的首位数字恰好等于 Ai−1 的末位数字 (2 ≤ i ≤ K)。 例如 12, 23, 35, 56, 61, 11 是接龙数列;12, 23, 34, 56 不是接龙数列,因为 56 的首位数字不等于 34 的末位数字。所有长度为 1 的整数数列都是接龙数列。 现在给定一个长度为 N 的数列 A1, A2, . . . , AN,请你计算最少从中删除多少 个数,可以使剩下的序列是接龙序列?

思路:动态规划,因为范围较大,所以需要边处理边满足条件,取得能是接龙数列的最大值,然后让总数减去这个最大值得到需要删除的个数。

#include <iostream>
#include <cstring>
#include <algorithm>
 
using namespace std;
 int g[10];
int main()
{
    int res=0;
    int n;
    cin>>n;
    for(int i=0;i<n;++i)
    {
        string s;
        cin>>s;
       int l=s[0]-'0',r=s[s.size()-1]-'0';
       int f=max(1,g[l]+1);
       g[r]=max(g[r],f);
       res=max(res,f);
    }
 
  
    cout<<n-res<<endl;
    
    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值