蓝桥杯练习题2(C/C++)

目录

1.排列字母

2.纸张尺寸

3.求和

4.数位排序

5.选数异或

6.消除游戏


1.排列字母

0排列字母 - 蓝桥云课

#include<stdio.h>
int main()
{
  // 请在此输入您的代码
  int swap;
  //储存字母的ASCII值
  int a[28]={'W','H','E','R','E','T','H','E','R','E','I','S','A','W','I','L','L','T','H','E','R','E','I','S','A','W','A','Y'};
  for(int i=27;i>=0;i--)
  {
    for(int j=i-1;j>=0;j--)
    {
      if(a[i]<a[j])
      {
        swap=a[i];
        a[i]=a[j];
        a[j]=swap;
      }
    }
  }
  for(int i=0;i<28;i++)
  {
    printf("%c",a[i]);
  }
  return 0;
}

2.纸张尺寸

0纸张尺寸 - 蓝桥云课

#include <stdio.h>
#include <math.h>
int main()
{
  int w = 1189, h = 841, a = 0;
  scanf("A%d", &a);
  for(int i = 0; i < a; i++)
  {
    int tmp = w;
    w = h;
    h = tmp / 2;
  }
  printf("%d\n%d", w, h);
  return 0;
}

3.求和

0求和 - 蓝桥云课

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  // 请在此输入您的代码
  long long count=0;
  for(int i=1;i<=20230408;++i)
  {
    count+=i;
  }
  printf("%lld",count);
  return 0;
}

4.数位排序

0数位排序 - 蓝桥云课

思路:

1.计算0到n每个整数的各位数之和,并将其存储在数组b

2.将0到n存储到a数组

3.按照题目要求,先各数之和排序,如果各位数字之和相同,则按照原数字大小排序

4.输出

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int b[N], a[N];

bool cmp(int x,int y)
{
  return b[x]<b[y] || b[x]==b[y]&&x<y;
}
int main()
{
  // 请在此输入您的代码
  int m,n;
  cin>>n>>m;
  for(int i=0;i<=n;i++)
  {
    int num=i;
    while(num)
    {
      b[i]+=num%10;
      num/=10;
    }
    a[i]=i;
  }
  sort(a+1,a+1+n,cmp);
  cout<<a[m]<<endl;
  return 0;
}

5.选数异或

0选数异或 - 蓝桥云课

思路:

1.利用异或运算的性质:a^b==x等价于a^x==b且b^x==a

2.哈希表存储已经遍历过的元素

3.对于每个元素,计算target=A[i]^x,根据异或运算的性质。如果target已经存在于哈希表中,说明存在两个元素和之前遍历过的某个元素异或结果为x,返回true

4.如果target不在哈希表中,将A[i]插入到哈希表中

5.如果遍历完整个子区间都没有找到满足条件的元素,返回false

#include <iostream>
#include<vector>
#include<unordered_set>
using namespace std;

bool checkXor(const vector<int>& A,int l,int r,int x)
{
  unordered_set<int> numSet;
  for(int i=l-1;i<r;++i)
  {
    int target=A[i]^x;//根据异或运算的性质,如果 a ^ b == x,那么 a ^ x == b 且 b ^ x == a
    //如果 target 已经存在于 numSet 中,说明存在两个元素 A[i] 和之前遍历过的某个元素异或结果为 x,返回 true
    if(numSet.find(target)!=numSet.end())//find 函数在未找到目标元素时,返回的是指向容器末尾的迭代器 end()
    {
      return true;
    }
    numSet.insert(A[i]);
  }
  return false;
}


int main()
{
  // 请在此输入您的代码
  int n,m,x;
  cin>>n>>m>>x;
  vector<int> A(n);
  for(int i=0;i<n;++i)
  {
    cin>>A[i];
  }
  for(int i=0;i<m;++i)
  {
    int l,r;
    cin>>l>>r;
    if(checkXor(A,l,r,x))
    {
      cout<<"yes"<<endl;
    }
    else
    {
      cout<<"no"<<endl;
    }
  }
  return 0;
}

6.消除游戏

0消除游戏 - 蓝桥云课

暴力解法:

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

string a;

int main()
{
  int i=1,j;
  cin>>a;

  long long t=0;
  //设置一个非常大循环上限,对字符串进行多次处理,直到字符串不再发生变化
  while(t++<9223372036854775807)
  {
    int p=0;
    //临时存储字符,以便再删除操作中进行比较和判断
    char b;
    int x=a.size();

    for(i=0;i<a.size();i++)
    {
      if(p==1)
      {
        int q=0;//标记是否进行了删除操作
        if(i+1<a.size() && b!=a[i] && a[i]==a[i+1])
        {
          b=a[i];
          a.erase(i,1);
          q=1;
        }
        else if(b==a[i] && a[i]!=a[i+1])
        {
          b=a[i+1];
          a.erase(i,2);
          q=1;
          i--;
        }
        if(q==0)
        {
          i--;
          p=0;
        }
      }
      //如果p等于0,说明处于初始判断状态
      else
      {
        if(i+2<a.size() && a[i]!=a[i+1] && a[i+2]==a[i+1])
        {
          //将下一个字符赋值给b
          b=a[i+1];
          //删除满足条件的两个字符
          a.erase(i,2);
          //字符串长度发生了变化,为了避免跳过下一个字符,将i--
          i--;
        }
        else if(i+2<a.size() && a[i]==a[i+1] && a[i+2]!=a[i+1])
        {
          b=a[i+2];
          a.erase(i+1,2);
          //将p设为1,进入特殊判断状态
          p=1;
        }
      }
    }
    int y=a.size();//记录处理完一轮后字符串a的长度
    if(x==y)//如果长度相等,说明再本轮处理中字符串没有发生变化,即已经无法再进行删除操作
    {
      break;
    }
  }
  if(a.size() == 0)
  {
    cout<<"EMPTY"<<endl;
  }
  else{
    cout<<a<<endl;
  }
  return 0;
}

思路:

1.在字符串首尾添加特殊字符'?'进行边界处理,初始化每个字符的左右邻指针

2.遍历字符串中的每个字符,找出满足删除条件的字符对,并将下标存入pos

3.循环处理pos中的下标,删除对应的字符,并更新左右邻指针,同时标记改字符已被删除。在删除过程中,记录新发现的可能需要删除的字符的左右邻字符下标,存储在临时向量p中

4.对临时向量p中的下标对应的字符进行检查,找出新的需要删除的字符,将其加入pos中

5.重复步骤3、4,直到pos向量中没有未处理的下标为止

#include <cstring>  // 包含字符串处理相关的函数,如 strlen
#include <cstdio>   // 包含标准输入输出函数,如 scanf 和 printf
#include <vector>   // 包含向量容器,用于存储动态数组
using namespace std;

// 定义一个类型别名 PII,它表示一个包含两个整数的二元组(pair<int, int>)
typedef pair<int,int> PII;

// 定义常量 N,用于数组的最大长度,这里是 1000010
const int N = 1e6 + 10;

// 定义字符数组 s,用于存储输入的字符串,下标从 1 开始使用
char s[N];

// 定义数组 l,l[i] 表示字符 s[i] 的左邻字符的下标
int l[N];

// 定义数组 r,r[i] 表示字符 s[i] 的右邻字符的下标
int r[N];

// 定义布尔数组 st,st[i] 表示字符 s[i] 是否已经被删除,初始为 false
bool st[N];

// 定义一个向量 pos,用于存储需要删除的字符的下标
vector<int>pos;

// 检查函数,用于判断字符 s[i] 是否满足删除条件
void check(int i)
{
    // 如果字符 s[i] 的左邻字符或右邻字符是 '?',则直接返回,不进行检查
    if(s[l[i]] == '?' || s[r[i]] == '?') return;

    // 如果字符 s[i] 与其左邻字符相同,且与其右邻字符不同
    if(s[i] == s[l[i]] && s[r[i]] != s[i])
        // 将字符 s[i] 和其右邻字符的下标加入到 pos 向量中
        pos.push_back(i), pos.push_back(r[i]);

    // 如果字符 s[i] 与其右邻字符相同,且与其左邻字符不同
    if(s[i] == s[r[i]] && s[i] != s[l[i]])
        // 将字符 s[i] 和其左邻字符的下标加入到 pos 向量中
        pos.push_back(i), pos.push_back(l[i]);
}

// 删除函数,用于从链表中删除字符 s[i]
void Remove(int i)
{
    // 更新 s[i] 左邻字符的右指针,使其指向 s[i] 的右邻字符
    r[l[i]] = r[i];
    // 更新 s[i] 右邻字符的左指针,使其指向 s[i] 的左邻字符
    l[r[i]] = l[i];
}

int main()
{
    // 从标准输入读取字符串,存储到 s 数组中,下标从 1 开始
    scanf("%s", s + 1);

    // 计算输入字符串的长度
    int n = strlen(s + 1);

    // 在字符串的首尾添加特殊字符 '?',用于边界处理
    s[0] = s[n + 1] = '?';

    // 初始化每个字符的左右邻指针
    for(int i = 1; i <= n; i++)
    {
        l[i] = i - 1;  // 字符 s[i] 的左邻字符下标为 i - 1
        r[i] = i + 1;  // 字符 s[i] 的右邻字符下标为 i + 1
    }

    // 对字符串中的每个字符进行检查,找出初始需要删除的字符
    for(int i = 1; i <= n; i++)
        check(i);

    // 初始化变量 i 用于遍历 pos 向量,cnt 用于记录删除的字符数量
    int i = 0;
    int cnt = 0;

    // 当 pos 向量中还有未处理的下标时,继续循环
    while(i < pos.size())
    {
        // 定义一个临时向量 p,用于存储新发现的可能需要删除的字符的左右邻字符下标
        vector<int> p;

        // 遍历 pos 向量中的每个下标
        for(; i < pos.size(); i++)
        {
            // 如果字符 s[pos[i]] 还未被删除
            if(!st[pos[i]])
            {
                // 从链表中删除字符 s[pos[i]]
                Remove(pos[i]);

                // 将字符 s[pos[i]] 的左邻字符和右邻字符的下标加入到 p 向量中
                p.push_back(l[pos[i]]);
                p.push_back(r[pos[i]]);

                // 标记字符 s[pos[i]] 已经被删除
                st[pos[i]] = true;

                // 增加删除的字符数量
                cnt++;
            }
        }

        // 对 p 向量中的每个下标对应的字符进行检查,找出新的需要删除的字符
        for(int j = 0; j < p.size(); j++)
        {
            if(!st[p[j]])
                check(p[j]);
        }
    }

    // 如果删除的字符数量等于字符串的总长度,说明字符串已被全部删除
    if(cnt == n)
    {
        // 输出 "EMPTY"
        puts("EMPTY");
    }
    else
    {
        // 遍历字符串中的每个字符
        for(int i = 1; i <= n; i++)
        {
            // 如果字符 s[i] 未被删除
            if(!st[i])
                // 输出该字符
                printf("%c", s[i]);
        }
        // 输出换行符
        printf("\n");
    }

    return 0;
}

再见

相关推荐
柠石榴3 分钟前
【练习】【贪心】力扣45. 跳跃游戏 II
c++·算法·leetcode·贪心
Kent_J_Truman8 分钟前
【01游戏——DFS】
算法
卜及中9 分钟前
【Go语言快速上手】第一部分:函数与错误处理
开发语言·后端·算法·golang
乱次序_Chaos35 分钟前
【无监督学习】主成分分析步骤及matlab实现
学习·算法·机器学习·matlab
青釉Oo44 分钟前
统计有序矩阵中的负数
java·数据结构·算法·leetcode·二分查找
Vitalia1 小时前
⭐算法OJ⭐矩阵的相关操作【动态规划 + 组合数学】(C++ 实现)Unique Paths 系列
算法·矩阵·动态规划
一匹电信狗1 小时前
C/C++内存管理:深入理解new和delete
c语言·开发语言·c++·ide·算法·visualstudio
白白糖1 小时前
Day 52 卡玛笔记
python·算法·力扣
Joyner20182 小时前
python-leetcode-斐波那契数
算法·leetcode·职场和发展
Joyner20182 小时前
python-leetcode-删除并获得点数
算法·leetcode·职场和发展