蓝桥杯真题讲解

目录

​编辑

第一题

题目链接

题目解析

代码原理

代码编写

第二题

题目链接

题目解析

代码原理

代码编写

本题总结

第三题

题目链接

题目解析

代码原理

代码编写

本题总结

第四题

题目链接

题目解析

代码原理

代码编写

本题总结

第五题

题目链接

题目解析

代码原理

代码编写

本题总结

第六题

题目链接

题目解析

代码原理

代码编写

第七题

题目链接

题目解析

代码原理

代码编写

错误的思路

使用了map

使用了hash

结果图

正确的思路

代码

结果图

本题总结

第一题

题目链接

19.九宫幻方 - 蓝桥云课

题目解析

代码原理

代码编写

#include <iostream>

#include<bits/stdc++.h>

using namespace std;

int all[8][9] = {{4,9,2,3,5,7,8,1,6},{2,9,4,7,5,3,6,1,8},{4,3,8,9,5,1,2,7,6},{8,3,4,1,5,9,6,7,2},{2,7,6,9,5,1,4,3,8},{6,7,2,1,5,9,8,3,4},{8,1,6,3,5,7,4,9,2},{6,1,8,7,5,3,2,9,4}};

int ok(int a[9])

{

    int cnt = 0, ans = -1;

    for(int i = 0; i < 8; i++)

    {

      bool truth = true;

      for(int j = 0; j < 9; j++)

      {

        if(a[j] == 0) continue;

        if(a[j] != all[i][j])

        {

          truth = false;

          break;

        }

      }

      if(truth)

      {

        cnt++;

        ans = i;

      }

    }

    if(cnt == 1) return ans;

    else return -1;

}

int main()

{

  // 请在此输入您的代码

  ios::sync_with_stdio(0);

  cin.tie(0);

  cout.tie(0);

  int data[9];

  for(int i = 0; i < 9; i++)

  {

    cin >> data[i];

  }

   int index =  ok(data);

  if(index == -1) cout << "Too Many" << endl;

  else

  {

    cout << all[index][0] << " " << all[index][1] << " " << all[index][2] << endl;

    cout << all[index][3] << " " << all[index][4] << " " << all[index][5] << endl;

    cout << all[index][6] << " " << all[index][7] << " " << all[index][8] << endl;

  }

  return 0;

}

第二题

题目链接

20.拉马车 - 蓝桥云课

题目解析

想必还是比较抽象,因此博主邀请了一位粉丝,与博主模拟了这个小游戏,下面的视频为大家详细解答

蓝桥杯真题讲解

代码原理

代码编写

#include<iostream>

#include<bits/stdc++.h>

using namespace std;

bool op(string& x, string& z)

{

  if(x.size() == 0) return false;//先判断进来的这个字符串a长度是否为0,如果为0则直接返回false

  char front = x[0];//取出字符串a的首元素

  long long i = z.find(front);//其次获取它在字符串z中的位置,即检查是否已经出现在了桌面

  bool ans = true;//用于控制出手顺序

  if(i != string::npos)//即桌面上已经有这张牌了

  {

    x.insert(x.end(), front);//先将front放回队尾

    for(int j = 0; j <= i; j++)

    {

      x.insert(x.end(), z[j]);//将z中的字符从0到i位置的字符尾插到a中

    }

    z.erase(0, i + 1);//插入结束后,要删除

  }

  else//桌面上没有这个字符

  {

    z.insert(z.begin(), front);

    ans  = false;

  }

  x.erase(x.begin());

  return ans;

}

int main()

{

  ios::sync_with_stdio(0);

  cin.tie(0);

  cout.tie(0);

  string a, b, c;

  cin >> a >> b;

  bool flagA = true, flagB = false;//先假设a赢,b输

  while(1)

  {

    if(flagA)

    {

      flagA = op(a,c);

      if(a.size() == 0)

      {

        cout << b << endl;

        break;

      }

      flagB = !flagA;

    }

    if(flagB)

    {

      flagB = op(b,c);

      if(b.size() == 0)

      {

        cout << a << endl;

        break;

      }

      flagA = !flagB;

    }

  }

  return 0;

}

本题总结

思路梳理:

核心模拟部分:先判断要操作的字符串的长度是否为0,如果为0直接返回false。反之,先取出字符串的第一个元素,再用这个元素去z(桌面上)找是否有这个字符(即是否有这张牌),如果有,那么将原本已经拿出来的字符放回该自己牌中的队尾,再将桌面上从第一个字符到第i个字符(就是与原本要插入的字符相同的位置)放回自己牌中的队尾,并且不改变ans的值(用于控制出手顺序)如果没有相同字符,将取出的字符放到桌面上字符串的队首,并且更改ans的值,注意记得删除原字符串里已经取出的字符。

次要部分(main函数里的):假设a能出牌,b不能出牌,然后进行操作(就是核心模拟部分),先判断a的字符串长度是否为0。如果为0,则输出b赢。如果不为0,则更改flagb的值(flaga的值取反即可)

第三题

题目链接

0次数差 - 蓝桥云课

题目解析

代码原理

用哈希表统计出每个字母的次数,用最大减最小

代码编写

#include<iostream>

#include<bits/stdc++.h>

using namespace std;

int main()

{

  ios:: sync_with_stdio(0);

  cin.tie(0);

  cout.tie(0);

  string s;

  int hash[26] = { 0 };

  cin >> s;

  for(int i = 0; i < s.size(); i++)

  {

      hash[s[i] - 'a']++;

  }

  int maxsize = 0, minsize = 0x3f3f3f3f;

  for(int i = 0; i < s.size(); i++)

  {

    maxsize = max(maxsize, hash[s[i] - 'a']);

    minsize = min(minsize, hash[s[i] - 'a']);

  }

  cout << maxsize - minsize << endl;

  return 0;

}

本题总结

本题又用到了前几篇所总结过的哈希表,那么在比赛中,凡是有涉及到统计的优先考虑这个哈希表。

第四题

题目链接

0小朋友崇拜圈 - 蓝桥云课

题目解析

代码原理

这里只给大家演示了当u和start都是1的情况,基本逻辑是模拟了下面这张图

后面的图,就劳烦各位小伙伴们自己去画一下图吧(太多了,画板画不下),结束条件这里有两种情况,第一种是start != u这种情况就直接return即可,第二种就是start == u 这种情况记得先更新结果再return。

代码编写

#include<iostream>

#include<bits/stdc++.h>

using namespace std;

const int N = 100010;

int a[N];

bool st[N];

int ans = -0x3f3f3f3f;

void dnf(int cur, int start, int len)

{

  if(st[cur])

  {

     if(cur == start)

     {

       ans = max(ans, len);

     }

     return;

  }

  st[cur] = true;//修改状态

  dnf(a[cur], start, len + 1);//递归

  st[cur] = false;//恢复状态

}

int main()

{

  ios::sync_with_stdio(0);

  cin.tie(0);

  cout.tie(0);

  int n = 0;

  cin >> n;

  for(int i = 1; i <= n; i++)

  {

    cin >> a[i];

  }

  for(int i = 1; i <= n; i++)

  {

    memset(st, false, sizeof(st));

    dnf(i, i, 0);

  }

  cout << ans << endl;

  return 0;

}

本题总结

第五题

题目链接

0等差数列 - 蓝桥云课

题目解析

代码原理

代码编写

#include<iostream>

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 100010;

ll a[N];

int gc(int c, int e)

{

  if(e == 0) return c;

  return gc(e, c % e);//递归

}

int main()

{

  ios::sync_with_stdio(0);

  cin.tie(0);

  cout.tie(0);

  int n = 0;

  cin >> n;

  for(int i = 0; i < n; i++)

  {

    cin >> a[i];

  }

  sort(a, a + n);

  int d = 0;

  for(int i = 1; i < n; i++)

  {

   d = gc(d, a[i] - a[i - 1]);

  }

  if(d == 0) cout << n;

  else cout << (a[n - 1] - a[0]) / d + 1 << endl;

  return 0;

}

本题总结

第六题

题目链接

0旋转 - 蓝桥云课

题目解析

代码原理

这里的代码原理,原本是不想写的,但博主考虑到看这篇文章的小伙伴们的水平都不一样,因此博主决定还是简单带一下代码原理这一部分

代码编写

#include<iostream>

#include<bits/stdc++.h>

using namespace std;

int main()

{

  ios::sync_with_stdio(0);

  cin.tie(0);

  cout.tie(0);

  int n = 0, m = 0;//n代表行,m代表列

  cin >> n >> m;

  int a[n][m];

  for(int i = 0; i < n; i++)

  {

    for(int j = 0; j < m; j++)

    {

       cin >> a[i][j];

    }

  }

  for(int i = 0; i < m; i++)//原来的列变成行

  {

    for(int j = n - 1; j >= 0; j--)//原来的行变成列

    {

      cout << a[j][i] << " ";//记得互换一下i和j的位置

    }

    cout << endl;

  }

  return 0;

}

第七题

题目链接

0单词分析 - 蓝桥云课

题目解析

代码原理

那么先前说过但凡出现统计次数的就用哈希表,这里博主其实想用哈希map的但是好像蓝桥杯比赛的编程环境无法使用,因此这题我们使用map来解题,当然这题也可以直接使用哈希来解题,那么代码我都放在下面供大家参考

代码编写

错误的思路
使用了map

#include<iostream>

#include<bits/stdc++.h>

using namespace std;

int main()

{

  ios::sync_with_stdio(0);

  cin.tie(0);

  cout.tie(0);

  string s;

  cin >> s;

  map<char, int> mp;

  for(int i = 0; i < s.size(); i++)

  {

      mp[s[i]]++;

  }

  int maxCount = 0;

  char maxChar;

  for(int i = 0; i < s.size(); i++)

  {

     if(maxCount < mp[s[i]])

     {

       maxCount = mp[s[i]];

       maxChar = s[i];

     }

  }

  cout << maxChar << endl;

  cout << maxCount << endl;

  return 0;

}

使用了hash

#include<iostream>

#include<bits/stdc++.h>

using namespace std;

int main()

{

  ios::sync_with_stdio(0);

  cin.tie(0);

  cout.tie(0);

  string s;

  cin >> s;

  int hash[26] = { 0 };

  for(int i = 0; i < s.size(); i++)

  {

    hash[s[i] - 'a']++;

  }

  int maxCount = -0x3f3f3f3f;

  char maxChar;

  for(int i = 0; i < s.size(); i++)

  {

    if(maxCount < hash[s[i] - 'a'])

    {

      maxCount = hash[s[i] - 'a'];

      maxChar = s[i];

    }

  }

  cout << maxChar << endl;

  cout << maxCount << endl;

  return 0;

}

结果图

正确的思路
代码

#include<iostream>

#include<bits/stdc++.h>

using namespace std;

const int N = 1010;

int main()

{

  ios::sync_with_stdio(0);

  cin.tie(0);

  cout.tie(0);

  string s;

  cin >> s;

  int hash[N] = {0};

  for(int i = 0; i < s.size(); i++)

  {

    hash[s[i] - 'a']++;

  }

  int maxCount = -0x3f3f3f3f;

  char maxChar;

  for(int i = 0; i < s.size(); i++)

  {

    if(maxCount <= hash[s[i] - 'a'])

    {

       if(maxCount < hash[s[i] - 'a'])

      {

         maxCount = hash[s[i] - 'a'];

         maxChar = s[i];

      }

      else if(maxCount == hash[s[i] - 'a'])

      {

            maxCount = hash[s[i] - 'a'];

            maxChar = s[i];

      }

    }

    

  }

  cout << maxChar << endl;

  cout << maxCount << endl;

  return 0;

}

结果图

博主翻阅其他博主的文章,找到了问题所在,那么首先感谢一下这位博主

博主翻阅了这位博主的文章,发现博主原本的思路是没有问题,但是少考虑了一种情况。那么是什么情况呢?听博主细细道来。

我们先来回忆一下,一开始的思路。

思路:利用哈希表或者map依次遍历,并且统计每个字母次数,然后设置最大值的初始值,再来一次循环,比较出最大的次数,最后输出出现最多出现次数的字母以及次数。

这个思路看似没有问题,但是还是存在一个小bug,就如同这位博主所说的一样,因为数组s中已经是按照字典序排列。但是存在一种情况,即一个字符串中有两个字母的出现次数是一样的,且都是最大次数,而我们只需要输出排在前面的结果即可。

本题总结

涉及统计次数的优先考虑哈希表,若是还有涉及其它变量则考虑使用map

本篇文章的内容就先到这里,关于map的题后面会涉及以及完整的一些用法也会有总结,精彩持续为您更新,敬请期待!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值