花瓣小跑 发表于 2025-4-10 10:38:19

【C++】 —— 笔试刷题day_13

一、牛牛冲钻五

标题描述

https://i-blog.csdnimg.cn/direct/4cf5035ddc054c509898724ce266deb4.png#pic_center
标题说,牛牛在玩炉石传说,现在牛牛进行了n场游戏,让我们判断牛牛上了几颗星。
   首先输入一个T,表示T组数据;
然后输入n和k,表示一个进行了n场数据,k表示连胜三场及以上得到的分数
然我们输出末了的星数和起始星数的差;
其中L表示失败,减一颗星;W表示胜利,如果连胜超过3场就得到k颗星,否则得到1可星。
算法分析

这道题算是比力简单的,我们只需要模拟一下整个过程就好了;
   标题中是连胜超过3场,就得到k颗星;
这里我们就要定义一个变量来记载连胜,当连胜场次超过3就得到k颗星;否则得到1颗星。
代码实现

#include<iostream>
using namespace std;

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
      int n,k;
      cin>>n>>k;
      int count = 0;
      int ret = 0;
      for(int i = 0;i<n;i++)
      {
            char ch;
            cin>>ch;

            if(ch == 'L')
            {
                ret-=1;
                count = 0;
            }
            else
            {
                count++;
                if(count>=3)
                  ret+=k;
                else
                  ret+=1;
            }
      }
      cout<<ret<<endl;
    }
    return 0;
}
二、最长无重复子数组

标题描述

https://i-blog.csdnimg.cn/direct/ce7bb08fe87549f0b1575ee8c48e61b3.png#pic_center
   这道题,给定一个数组arr,让我们找到其中没有重复元素的最长子数组;返回这个最长子数组的长度。
算法分析

看到这道题,了解过滑动窗口的可以说是一眼秒了,这种找子串题目。
现在我们先来看暴力解法:
   分别从0、1、…n位置向后遍历,寻找没有重复字符的子串;
这里在寻找没有字符元素的子串时,我们需要记载区间内每一个元素出现的次数,那这里就要用到一个hash去记载。
https://i-blog.csdnimg.cn/direct/ab1b6a04e5524b1da3ded647e80efb6c.png#pic_center
我们看上图,当i在第一个位置找到没有重复元素的最长子数组时;
如果我们i++后,让j再从i位置开始向后遍历,如果i位置对应的元素不等于j位置对应的元素,那肯定还是走到和从0位置最长的那一个位置。
那这样我们就没有须要让j再从i位置向后遍历了,而是i++,直到i遍历过和j位置元素相称的那一个位置。
那这样我们还得窗口的主要思想就出来了:
   

[*]入窗口:将right位置的元素放到hash表中。
[*]出窗口:当区间内出现了重复的元素,那就进行出窗口操纵,直到区间内没有重复的元素。
[*]更新结果:出窗口操纵之后,区间肯定是满足条件的,更新结果即可。
代码实现

class Solution {
public:
    int hash={0};
    int maxLength(vector<int>& arr) {
      // write code here
      int ret = 0;
      int left = 0, right = 0;
      while(right<arr.size())
      {
            hash]++;
            while(hash] > 1)
            {
                hash]--;
                left++;
            }
            ret = max(ret,right - left+1);
            right++;
      }
      return ret;
    }
};
三、重排字符串

标题描述

https://i-blog.csdnimg.cn/direct/0af01b06d78147b884326dd6135020c5.png#pic_center
   标题给了我们一个字符串,然后让我们判断,这个字符串可否通过重新排列(只改变字母的顺序,不改变数目),让相邻的字母都不相同。
如果不可以就输出no;如果可以,就输出yes,并输出其中一种排列方式。
算法分析

这里这道题,标题描述很简单,但是我们会感觉到无从动手;
这个就直接说思路了,就是使用贪心
   我们先来看它们示例:aabbccc,它可以通过排列变成相邻字符都不相同的字符;
这里,我们先来排列ccc,由于c出现的次数最多
https://i-blog.csdnimg.cn/direct/4df75fb1b80d4195b1fb090d0accbb2c.png#pic_center
观察上图,很显然,每隔一个位置,放置一个字符,这样那个放置一样的字符数最多(那我们就可以使用这一点来判断,是否能够通过排列构成相邻元素是否都不相同)
   什么意思呢?
如果每隔一个位置,放置一个字符,这样如果我们出现次数最多的字符,如果它从第一个位置开始,每隔一个位置放置一个,直到末了,还有剩余,那肯定不能通过排列变成满足条件的字符串。
如果还没到末了一个,次数最多的字符就放置完了,那其他的还是按照每隔一个位置放置一个,就肯定能够通过排列变成满足条件的字符串。
我们在分析,当出现数目最多的字符,它出现的次数 > 给定字符串的长度+1的一半,那可以就不能通过排列来满足条件了。(这里就不叙述原因了,通过分析上述每隔一个位置放置一个字符,极端情况可以分析出来。
那如果可以通过排列满足条件,那我们就要进行排列了。
   排列我们遵循的大体规则还是每隔一个位置,放置一个字符。
这里我们需要先对出现此时最多的字符先进行放置,放置完再依次放置其他字符即可
代码实现

#include <iostream>
#include <string>
using namespace std;
int main()
{
    int n;
    int cnt = {0};
    cin>>n;
    int MaxCount = 0;
    char MaxChar = 0;
    for(int i=0;i<n;i++)
    {
      char ch = 0;
      cin>>ch;
      cnt++;
      if(cnt > MaxCount)
      {
            MaxCount = cnt;
            MaxChar = ch;
      }
    }
    if(MaxCount > (n+1)/2)
      cout<<"no"<<endl;
    else
    {
      cout<<"yes"<<endl;
      string ret(n,0);
      //先放置出现次数最多的字符
      int i =0;
      while(MaxCount--)
      {
            ret = MaxChar;
            i+=2;
      }
      //放置其他字符
      for(int j = 0;j<26;j++)
      {
            if(j+'a' != MaxChar)
            {
                while(cnt--)
                {
                  if(i>=n) i = 1;
                  ret = j+'a';
                  i+=2;
                }
            }
      }
      cout<<ret<<endl;
    }
    return 0;
}
到这里,本日刷题就结束了
   简单总结:本日标题解决方法:模拟整个过程、滑动窗口、贪心。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【C++】 —— 笔试刷题day_13