目录
提供2个链接
P1525 - [蓝桥杯2020初赛] 单词分析 - New Online Judge (ecustacm.cn)
前言
开始2023-4月蓝桥杯备赛
一、考察内容
数组和字符串基本的输入输出,注意数组超限问题。
二、题目,代码,分析
1.题目
输入
输入一行小写字母
长度不超过 1000
输出
输出两行,第一行包含一个英文字母,表示单词中出现得最多的字母是哪个。
如果有多个字母出现的次数相等,输出字典序最小的那个。
第二行包含一个整数,表示出现得最多的那个字母在单词中出现的次数。
示例 1
输入
lanqiao
输出
a
2
示例 2
输入
longlonglongistoolong
输出
o
6
难度: 简单 标签: 字符串, 暴力, 2020, 省赛
2.代码
#include<iostream>
#include<string>//.length(),只能求字符串长度
#include<stdio.h>//getchar()
using namespace std;
int main()
{
int a[26] = {0};
//输入方式2:
/*
char s;
while((s = getchar()) != '\n')
a[s - 'a']++;
*/
//*********************输入方式1*****************************
string s;
cin>>s;
for(int i = 0; i < s.length(); i++)
a[s[i]-'a']++;//数组元素a[i]表示对应字母出现次数,比如a[1] == 3,表示b出现3次
//***********************************************************
int Max = a[25], Maxj = 25;
for(int i = 25; i >= 1; i--)//如果出现次数一样,输出字典序最小的,就逆序比较
{
if(a[i-1] >= Max)
{
Max = a[i-1];//因为这里到i-1,所以上面要i>=1,否则超限
Maxj = i-1;
}
}
char z = 'a' + Maxj;//整型转字符
cout<<z<<endl;
cout<<Max<<endl;
return 0;
}
3.分析
1,第一个for循环中,a[s[i]-'a']++类似十六转十进制中的if('0' <= x[i] && x[i] <= '9')
sum += (x[i] - '0');这里的x[i]-'0'和s[i]-'a'都是字符转ASCII值的例子
2,第二个for循环的条件中,我一开始令i>=0,结果一直输出一串无关数字,后来才发现后面有i-1,会超限
三,相关拓展
1,十六进制转十进制(代码和详细注释)
(注释里有我最开始的各种错误分析)
#include<iostream>
#include<stdio.h> //scanf(),printf()
#include<string> //字符串类型变量头文件,length()需要字符串头文件
using namespace std;
int main()
{
string x;
while(cin>>x)//此处不用while(scanf("%s",x) != EOF),
//输出一直是0,因为%s只能用在char类型上,不能用在string类型
{
long long sum = 0; //sum放在while里,否则会一直叠加
int n = x.length(); //求字符串长度,也要放在while里
for(int i = 0; i < n; i++) //注意:此处i必须从0开始,
//因为字符串第一位是0,i = 0才对
{
if('0' <= x[i] && x[i] <= '9') //条件不要写一块,要用&&或者||分开,否则变成bool判断
sum += (x[i] - '0');
else if('A' <= x[i] && x[i] <= 'F')
sum += (x[i] - 'A' + 10);
else if('a' <= x[i] && x[i] <= 'f')
sum += (x[i] - 'a' + 10);
if(i < n - 1)
sum *= 16; //运算顺序很重要,放的位置很重要
}
cout<<sum<<endl; //放在while里
}
return 0;
}
输入,输出:
1,
ABCDD1234
46118277684
2,
100
256
2,十进制转十六或八(代码较长,但思路清晰)
#include<iostream>
using namespace std;
int a[1000];
char b[1000]; //严重问题:十六进制这应该用char,用int会出现no match for operator<<
void jinzhi_eight(int n) //这里用值传递是因为不存在传递
//,只是最后cout输出了数组
{
int i = 0; //要记熟十进制转其他的套路
if(n < 0)
n = -n;
while(n)
{
a[i] = n % 8;
n /= 8;
i++;
}
for(int j = i - 1; j >= 0; j--)
{
cout<<a[j];//一般构造函数cout结尾就是值传递,return结尾就是引用传递
}
}
void jinzhi_sixteen(int m) //1,没有return值的函数,不能放在cout<<后或接<<,
//否则会报错:no match for operator <<
{
int i = 0;
if(m < 0)
m = -m;
while(m)
{
b[i] = m % 16;
m /= 16;
i++;
}
for(int j = i - 1; j >= 0; j--)
{
if(b[j] >= 10 && b[j] <= 15)//但字符数组b一开始接收的是整数
{
b[j] = b[j] + 'a' -10;//开头声明char b[1000],自动转换成字符
}
else
b[j] = b[j] + '0';//因为开头声明char b[1000],自动转换
cout<<b[j];
}
}
int main()
{
int n;
while(cin>>n)
{
if(n < 0)
{
cout<<n<<" = -";
jinzhi_eight(n);//1,没有return值的函数,不能放在cout<<后或接<<,
cout<<"(8)"; //否则会报错:no match for operator <<
cout<<" = -";
jinzhi_sixteen(n);
cout<<"(16)"<<endl;
}
else
{
cout<<n<<" = ";
jinzhi_eight(n);
cout<<"(8)";
cout<<" = ";
jinzhi_sixteen(n);
cout<<"(16)"<<endl;
}
}
return 0;
}
输入,输出
1,
8
8 = 10(8) = 8(16)
2,
128737
128737 = 373341(8) = 1f6e1(16)
总结
多刷。。简单题争取第一次做出来,复杂点的争取第二三次做出来,难以理解的概念先放放,过一两周可能突然就悟了
🍉补充
有人提问,所以我又做了一次,下面是两个网站都能Ac的代码
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
int a[30];
int main()
{
string s;
cin>>s;
for(int i = 0; i < s.size(); ++i)
a[s[i] - 'a' + 1] += 1; //假如此时是a,那么a[1] += 1
int num = 0, ans = 0;
for(int i = 26; i >= 1; --i) {
if(a[i] >= ans) {
num = i;
ans = a[i];
}
}
char z = 'a' + num - 1;
cout<<z<<endl<<ans;
return 0;
}