第28场 蓝桥杯入门赛 题解

本蒟蒻第一次写题解,虽然题很简单可能会有写的很烂的代码
还请多多指教( ˘͈ ᵕ ˘͈♡)

难度:

  1. 签到:A B C D F
  2. 中等:E

A.胜利终将属于你

签到题:直接输出"I will fight and win"就可以了

B.团队赛

签到题:直接根据题意进行三次判断就可以了

int main()
{
  int a,b,c;
  cin>>a>>b>>c;

  if(a>b+c)
  {
    cout<<'l'<<endl;
    return 0;
  }
  if(b>a+c)
  {
    cout<<'q'<<endl;
    return 0;
  }
  if(c>a+b)
  {
    cout<<'b'<<endl;
    return 0;
  }

  cout<<-1<<endl;
}

C.蓝桥速算

这道题多举几个例子找一下规律就可以做出来了

题目简单来说就是给出l和r:

  • 如果l-r是奇数,如:1 4(也就是+1 -2 +3 -4=-2)
    最后sum就会减去(l-r+1)/2
  • 若是偶数:如1 5(+1 -2 +3 -4 +5=3)
    最后sum就会加上(l-r)/2 + r

代码如下:

#include <iostream>
using namespace std;
int main()
{
  long long n,q;
  cin>>n>>q;

  long long d,sum=0;
  for(int i=0;i<n;i++)
  {
    cin>>d;
    sum+=d;
  }

  long long l,r;
  for(int i=0;i<q;i++)
  {
    cin>>l>>r;
    if((r-l)&1==1)
    {
      sum-=(r-l+1)/2;
    }
    else
    {
      sum+=(r-(r-l)/2);
    }
  }

  cout<<sum<<endl;

  return 0;
}

D.浓缩咖啡液

签到题:只要判断目标浓度在输入的最大浓度和最小浓度之间就可以了

代码如下:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
    int T;
    cin >> T;

    while (T--)
    {
        int N, M;
        cin >> N >> M;

        vector<int> A(N);
        for (int i = 0; i < N; ++i)
        {
            cin >> A[i];
        }

        int min_A = *min_element(A.begin(), A.end());
        int max_A = *max_element(A.begin(), A.end());
        //这里的星号是解引用

        if (M >= min_A && M <= max_A)
        {
            cout << "YES" << endl;
        }
        else
        {
            cout << "NO" << endl;
        }
    }

    return 0;
}

E.破译密码

E题应该是这次比赛最难的题了(其实是本蒟蒻不会)
我还专门问了下AI,说是Johnson's算法
这里讲一下:
johnson算法用于解决两阶段流水车间调度问题

  • 有n个任务需要两个人解决
  • 每个任务必须由第一个人先加工后,第二个人才能加工
  • 每个任务Ni在第一个人需要的时间为Ai,第二个人为Bi

算法核心思想
把所有任务分成AB两组

  • A组:若任务在第一个人更快,就尽快让第一个人处理,让第二个人尽快开始工作
  • B组:若任务在第二个人更快,就尽量往后放,避免第二个人空闲

A组升序排列:让第二个人尽快开始工作
B组降序排列:避免传输时间长的任务被拖延到队列末尾,从而减少后续任务的等待时间

AI代码如下:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

struct Task {
    int a;
    int b;
    bool operator<(const Task& other) const {
        return a < other.a; // 默认按破译时间升序排序(用于第一类任务)
    }
};

// 比较函数:按传输时间降序排序(用于第二类任务)
bool compareSecondGroup(const Task& t1, const Task& t2) {
    return t1.b > t2.b;
}

int main() {
    int n;
    cin >> n;

    vector<Task> tasks(n);
    for (int i = 0; i < n; ++i) {
        cin >> tasks[i].a;
    }
    for (int i = 0; i < n; ++i) {
        cin >> tasks[i].b;
    }

    // 将任务分为两组
    vector<Task> group1, group2;
    for (const auto& task : tasks) {
        if (task.a < task.b) {
            group1.push_back(task); // 第一类:A < B
        } else {
            group2.push_back(task); // 第二类:A >= B
        }
    }

    // 排序
    sort(group1.begin(), group1.end());            // 第一类按A升序
    sort(group2.begin(), group2.end(), compareSecondGroup); // 第二类按B降序

    // 合并任务顺序
    vector<Task> orderedTasks;
    orderedTasks.insert(orderedTasks.end(), group1.begin(), group1.end());
    orderedTasks.insert(orderedTasks.end(), group2.begin(), group2.end());

    // 计算总时间
    int currentTime = 0;    // 破译累计时间
    int transmitTime = 0;   // 传输累计完成时间

    for (const auto& task : orderedTasks) {
        currentTime += task.a;
        // 传输开始时间取破译完成时间和上一次传输完成时间的较大者
        int startTransmit = max(currentTime, transmitTime);
        transmitTime = startTransmit + task.b;
    }

    cout << transmitTime << endl;

    return 0;
}

F.插入数字

中等:
正常来说除了首位不能插入0,其他位置都能插入10个数字(0~9)
但是为了避免产生重复结果,这一位插入的数不能和前面的原数一样
举例:
2 3
首位插入2:
2 2 3
第二位插入2:
2 2 3

所以只要这一位插入的数不和前一位原数一样就可以
因此每一位都只能插入9个数字
所以我们只需要获取原数的位数n,输出(n+1)*9就ok了

这个代码是最简单的一版,不过不知道能不能过,因为蓝桥杯犯病一直轮询超时
代码如下:

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

int main() 
{
    string N;
    cin >> N;
    int L = N.size();
    
    cout << (L+1)*9 << endl;
    return 0;
}
posted @ 2025-04-06 16:48  颜开Young  阅读(29)  评论(0)    收藏  举报