目录
1.排列字母
#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.纸张尺寸
#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.求和
#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.数位排序

思路:
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.选数异或

思路:
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.消除游戏

暴力解法:
#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;
}
再见