[TOC]
华为机试题库共103道题目,其中入门级5道,简单级46道,中等级36道,较难级13道,困难级3道。计划在7天内共完成入门级,简单级,中等级的共计87道题目,则每天应当完成13道左右。计划每天完成:
入门级:1道 简单级:7道 中等级:6道
一、基础数学篇(12)
1、HJ7 取近似值(入门)
#include<bits/stdc++.h>
using namespace std;
int main(){
float n;
cin>>n;
int b=n;
float c=n-b;
if(c>=0.5){
b+=1;
}
cout<<b;
return 0;
}
2、HJ97 记负均正
#include<bits/stdc++.h>
using namespace std;
int main(){
// 获取输入
int n,tmp;
cin>>n;
int num_1=0;// 正数个数
int num_2=0;// 负数个数
double sum=0.0;
while(n--){
cin>>tmp;
if(tmp>0) {
sum+=tmp;
num_1++;
}
else if(tmp<0)num_2++;
}
double mean=0.0;
if(num_1!=0) mean=sum/num_1;
printf("%d %.1f\n",num_2,mean);
return 0;
}
3、HJ100 等差数列
#include<bits/stdc++.h>
using namespace std;
int getSum(int n,int& sum){
int res=0;
if(n==1) res=2;
else res+=getSum(n-1,sum)+3;
sum+=res;
return res;
}
int main(){
// 获取输入
int n;
cin>>n;
// 递归调用
int sum=0;
getSum(n,sum);
cout<<sum;
}
4、HJ72 百钱买百鸡问题
#include <bits/stdc++.h>
using namespace std;
/* 本题是一道解方程题,答案是唯一的,可以直接输出
但是为了
*/
int main(){
int n;
cout<<"0 25 75\n4 18 78\n8 11 81\n12 4 84"<<endl;
// for(int i=0;i<=100;i++)
// {
// for(int j=0;j<=100-i;j++)
// {
// if(5*i+j*3+(100-i-j)/3==100&&(100-i-j)%3==0)
// {
// cout<<i<<" "<<j<<" "<<100-i-j<<endl;
// }
// }
// }
return 0;
}
5、HJ108 求最小公倍数
#include <bits/stdc++.h>
using namespace std;
/*求2个数的最小公倍数,其一定是2个数中最大数的整数倍
所以遍历的时候可以,最小是2个数中的最大值,最大是2个数的乘积,每次加一个最大数
*/
int main(){
// 获取输入
int n1,n2;
cin>>n1>>n2;
// 计算两个数的最小公倍数
int max_v=n1*n2;
int inin_v=max(n1,n2);// 最小的可能公倍数
int res=inin_v;
for(;res<=max_v;res+=inin_v){
if(res%n1==0&&res%n2==0) break;
}
cout<<res;
}
6、HJ73 计算日期到天数转换
#include<bits/stdc++.h>
using namespace std;
int getDays(int y,int m){
int days=0;
// 二月份的天数
if(m==2)
// 如果是闰年,该年份能被 4 整除同时不能被 100 整除;或者该年份能被400整除。
if((y%4==0&&y%100!=0)||y%400==0) days=29;
// 如果不是闰年
else days=28;
// 天数为31的月份
else if(m==1||m==3||m==5||m==7||m==8||m==10||m==12)
days=31;
// 天数为30的月份
else if(m==4||m==6||m==9||m==11)
days=30;
return days;
}
int main(){
// 获取输入
int y,m,d;
cin>>y>>m>>d;
// 处理字符串
int res=0;
for(int i=1;i<m;++i){
res+=getDays(y,i);
}
res+=d;
// 输出结果
cout<<res<<endl;
return 0;
}
7、HJ76 尼科彻斯定理
#include <bits/stdc++.h>
using namespace std;
/* 本题是求一个正整数m的m个连续奇数
这m个连续奇数正好是一个等差序列,假设第一个项是i,则第m项是i+*2(m-1)
则连续n个连续奇数和=(i+i+*2(m-1))*m/2=m*m*m
求得 i=m*m-m+1; 则输出得等差序列即可
*/
int main(){
// 获取输入
int m;
cin>>m;
int i=m*m-m+1;//m个连续奇数的第一个数
// 输出m个连续奇数
while(m--){
if(m==0) cout<<i;//最后一个数后不需要"+"
else cout<<i<<"+";
i=i+2;//下一个奇数
}
return 0;
}
8、HJ53 杨辉三角的变形
#include<bits/stdc++.h>
using namespace std;
/*本题是一道杨辉三角的找规律题型:
只有n为1,2时,没有出现偶数,剩下的按照2 3 2 4的规律每四行循环一次。
n=1,index=-1
n=2,index=-1
n=3,index=2
n=4,index=3
n=5,index=2
n=6,index=4
n=7,index=2
n=8,index=3
n=9,index=4
n=10,index=2
*/
int main(){
// 获取输入
int n;
cin>>n;
// 处理
if(n==1||n==2) cout<<-1<<endl;
else if(n%4==3) cout<<2<<endl;
else if(n%4==0) cout<<3<<endl;
else if(n%4==1) cout<<2<<endl;
else if(n%4==2) cout<<4<<endl;
return 0;
}
9、HJ99 自守数
#include<bits/stdc++.h>
using namespace std;
/*
求自守数的解题思路
规律:个位数为 0、1、5、6 的数才可能是自守数,故采用筛选法,只判断符合该条件的数
思路1:可以把整数(数及其平方)转换为字符串,通过比较长字符串的末尾是否与短字符串相同即可
如:25 * 25 = 625,字符串'625'的末尾'25'与字符串'25'的相同
思路2:若该数的平方与该数的差,去模该数对应的各个进制位均等于零,则该数为自守数
如:25 * 25 = 625,625 - 25 = 600,600 % (10*1) = 0,600 % (10 * 2) = 0
*/
int main(){
// 获取输入
int n;
cin>>n;
// 递归调用
int res=0;
for(int i=0;i<=n;++i){
//仅对个位数符合条件的数执行自守数的判断(没有该判断也能通过,加上效率更高)
if((i%10 == 0) || (i%10 == 1) || (i%10 == 5) || (i%10 == 6)){
long j = i*i;
string s1=to_string(i);
string s2=to_string(j);
int n1=s1.length();
int n2=s2.length();
if(s2.substr(n2-n1,n1)==s1) res++;
}
}
cout<<res;
}
10、HJ56 完全数计算
#include <bits/stdc++.h>
using namespace std;
/*求n以内的完全数,首先1肯定不是,所以遍历到n时应该从2开始
那么如果判断每个i是否是完全数呢?暴力搜索
遍历[2,i/2]中的数,计算除自身以外的约数和
*/
int main(){
int n; //待输入的数
cin>>n;
int count=0; //计数器
//遍历从2到n的每一个数,并在下一层for计算是否为完全数
for(int i=2;i<=n;i++)
{
int sum=1; //每个数都包含1这个因数
// 遍历[2,i/2]中的数,计算除自身以外的约数和
for(int j=2;j<=i/2;j++) //除以2:根据题干推出的缩小i范围的方法
{
if(i%j==0)
sum=sum+j;
}
// 如果约数和==i,说明是完全数
if(i==sum) count++;
}
cout<<count<<endl;
return 0;
}
11、HJ6 质数因子
#include <bits/stdc++.h>
using namespace std;
/*求一个正整数n的质数因子,首先1肯定不是,所以遍历到n时应该从2开始
正整数中质数有无穷多个。某个数的质因数是有限的,
而且除了最大的质因数,其他质因数的大小不会超过该数开方。
最坏的情况就是总共有两个质因数,每个质因数都是最大质因数,
那么该质因数就达到了上限:原数的开方。
所以解题思路为遍历2到该数开方的数,将原数依次相除,每个数都除到有余数为止;
那么其中非质因数的数相当于不会遍历到。直到最后剩下一个最大质因数或者1。
*/
int main(){
// 获取输入
int n;
cin>>n;
// n的质数因子的范围[2,sqrt(n)]
for (int i = 2; i <= sqrt(n); ++i){
// 如果n可以整除i,那么i就是一个质数因子
while(n % i == 0){
cout << i << ' ';
n = n / i;// i
}
}
if(n != 1)
cout << n;
return 0;
}
12、HJ60 查找组成一个偶数最接近的两个素数
#include<bits/stdc++.h>
using namespace std;
// 判断一个数是否是素数/质数
bool is_prime(int n){
// 质数:一个大于1的、除了1和自身都不能整除的自然数
for(int i=2;i<n;i++){
if(n%i==0) return false;
}
return true;
}
int main(){
// 获取输入
int n;
cin>>n;
// 遍历n的质数因子[2,sqrt(n)]
int n1=0;
int n2=0;
int min_v=n;//最小的差值
for(int i=sqrt(n);i<=n;i++){
// 如果i<n-i并且i和n-i都是素数
if(i<=n-i&&is_prime(i)&&is_prime(n-i)){
int cur_min=n-i-i;
if(cur_min<min_v){
min_v=cur_min;
n1=i;
n2=n-i;
}
}
}
cout<<n1<<endl<<n2<<endl;
return 0;
}
二、哈希篇(10)
1、HJ84 统计大写字母个数
#include <bits/stdc++.h>
using namespace std;
int main(){
// 获取n个候选人的输入
string s;
getline(cin,s);
// 输出大写字母的个数
int res=0;
for(char c:s){
if(c>='A'&&c<='Z') res++;
}
cout<<res;
}
2、HJ10 字符个数统计
#include<iostream>
#include<string>
#include<unordered_map>
using namespace std;
int main(){
string s;
cin>>s;
unordered_map<int,int> dict;
for(char c:s){
dict[c]++;
}
cout<<dict.size()<<endl;
return 0;
}
3、HJ40 统计字符
#include <iostream>
#include <string>
using namespace std;
int main(){
// 获取输入
string s;
getline(cin, s);
// 排序
int a=0;
int A=0;
int space=0;
int num=0;
int other=0;
for(char c:s){
if(c>='A'&&c<='Z') A++;
else if(c>='a'&&c<='z') a++;
else if(c==' ') space++;
else if(c>='0'&&c<='9') num++;
else other++;
}
cout <<A+a<<endl;
cout <<space<<endl;
cout <<num<<endl;
cout <<other<<endl;
return 0;
}
4、HJ9 提取不重复的整数(入门级)
#include<bits/stdc++.h>
using namespace std;
int main(){
unordered_map<int,int> dict;// 统计频率
int num;
cin>>num;
//从右向左扫描整数
for(;0 < num;num /= 10){
int cur=num%10;// 获取当前位的数字
// 如果cur的数字为0说明之前没出现过
if (!dict.count(cur)){
dict[cur] = 1;//标记
cout<<cur;
}
}
return 0;
}
5、HJ2 计算某字符出现次数
方法一:转换为小写后遍历
#include <iostream>
#include <string>
using namespace std;
int main(){
// 获取输入
string s;
getline(cin, s);
char c;
cin>>c;
// 计算结果
c=tolower(c);
int res = 0;
for (char i : s) {
if (tolower(i) == c) {
++res;
}
}
cout <<res;
}
方法二:转换为小写加入哈希表
#include<iostream>
#include<string>
#include<unordered_map>
using namespace std;
int main()
{
// 获取输入
string s;
getline(cin, s);
char c;
cin>>c;
// 计算结果
c=tolower(c);
unordered_map<char, size_t> dict;
for (auto i : s) {
++dict[tolower(i)];
}
cout << dict[tolower(c)] << endl;
}
6、HJ81 字符串字符匹配
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
int main(){
// 获取输入
string s1;
string s2;
unordered_map<char,int> dict;
while(getline(cin, s1)){
getline(cin, s2);
bool flag=true;
for(char c:s2) dict[c]++;//统计长字符串中的所有字符频率
// 遍历短字符串
for(char c:s1){
// 如果有一个字符在字典中不存在则结果为false
if(dict.count(c)==0){
flag=false;
break;
}
}
if(flag) cout<<"true"<<endl;
else cout<<"false"<<endl;
}
}
7、HJ8 合并表记录
#include<iostream>
#include<string>
#include<map>
using namespace std;
int main(){
int n;
cin>>n;
map<int,int> dict;
while(n--){
int key,value;
cin>>key>>value;
dict[key]+=value;
}
for(auto kv:dict){
cout<<kv.first<<" "<<kv.second<<endl;
}
return 0;
}
8、HJ23 删除字符串中出现次数最少的字符
#include<iostream>
#include<string>
#include<unordered_map>
using namespace std;
int main(){
// 获取输入
string s;
getline(cin,s);
// 统计频率
unordered_map<char, int> dict;
for(char c:s){
dict[c]++;
}
int min_q=20;
for(auto it:dict){
if(it.second<min_q) min_q=it.second;
}
// 从最后一个字符向前走
int left=0;
int right=0;
int n=s.length();
while(right<n){
if(dict[s[right]]==min_q){
right++;
}
else{
s[left++]=s[right++];
}
}
cout<<s.substr(0,left);
return 0;
}
9、HJ94 记票统计
#include <bits/stdc++.h>
using namespace std;
int main(){
// 获取n个候选人的输入
int n;
cin>>n;
map<string,int> dict;// 字典,统计候选人票数
vector<string> arr;// 数组,按照输入顺序保存,为了输出
dict["Invalid"]=0;
string tmp;
while(n--){
cin>>tmp;
dict[tmp]=0;
arr.push_back(tmp);
}
arr.push_back("Invalid");
// 获取k个选票的输入
int k;
cin>>k;
while(k--){
cin>>tmp;
if(dict.count(tmp))dict[tmp]++;// 有效选票
else dict["Invalid"]++;// 无效选票
}
// 输出结果
for(auto s:arr) cout<<s<<" : "<<dict[s]<<endl;
}
10、HJ102 字符统计
#include <bits/stdc++.h>
using namespace std;
class mycomp{
public:
bool operator()(const pair<char,int>& a,const pair<char,int>& b){
if(a.second==b.second){
return a.first>b.first;
}
else{
return a.second<b.second;
}
}
};
int main(){
// 获取输入
string s;
unordered_map<char,int> dict;
priority_queue<pair<char,int>,vector<pair<char,int>>,mycomp> que;
while(getline(cin, s)){
for(char c:s) dict[c]++;//统计长字符串中的所有字符频率
// 遍历短字符串
for(auto p:dict){
que.push(p);
}
// 输出
while(!que.empty()){
auto p=que.top();
que.pop();
cout<<p.first;
}
cout<<endl;
}
}
三、数组篇(8 )
1、HJ11 数字颠倒
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main(){
int n;
cin>>n;
string s=to_string(n);// 转换为数字
reverse(s.begin(),s.end());
cout<<s<<endl;
return 0;
}
2、HJ58 输入n个整数,输出其中最小的k个
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main(){
// 获取输入
int n,k;
cin>>n>>k;
int temp;
vector<int> arr;
while(n--){
cin>>temp;
arr.push_back(temp);
}
// 返回结果
sort(arr.begin(),arr.end());
for(int i=0;i<k;++i){
cout<<arr[i]<<" ";
}
return 0;
}
3、HJ101 输入整型数组和排序标识,对其元素按照升序或降序进行排序
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
bool cmp(int a,int b){
return a>b;
}
int main(){
// 获取输入
int n;
cin>>n;
int temp;
vector<int> arr;
while(n--){
cin>>temp;
arr.push_back(temp);
}
int k;
cin>>k;
// 返回结果
if(k==0){
sort(arr.begin(),arr.end());
}
else if(k==1){
sort(arr.begin(),arr.end(),cmp);
}
// 输出结果
for(int i=0;i<arr.size();++i){
cout<<arr[i]<<" ";
}
return 0;
}
4、HJ15 求int型正整数在内存中存储时1的个数
#include <bits/stdc++.h>
using namespace std;
int main(){
// 获取输入
int n;
cin>>n;
int res=0;
while(n){
if(n%2==1) res++;
n=n/2;
}
cout<<res;
}
5、HJ62 查找输入整数二进制中1的个数
#include<bits/stdc++.h>
using namespace std;
int main(){
// 获取输入
int n;
while(cin>>n){
int res=0;
while(n){
if(n%2==1) res++;
n=n/2;
}
cout<<res<<endl;
}
return 0;
}
6、HJ86 求最大连续bit数
#include <bits/stdc++.h>
using namespace std;
int main(){
// 获取输入
int n;
cin>>n;
//转换为二进制
string s;// 该数字的二进制格式
while(n){
s=to_string(n%2)+s;
n=n/2;
}
// 记录该二进制下的连续1的个数
int res=0;
for(int i=0;i<s.length();++i){
// 从i出发,计算连续1的个数tmp
int tmp =0; //计数器,存放临时变量
while(i<s.length()&&s[i]=='1'){
tmp++;
i++;
}
// 保存历史最大值
res=max(res,tmp);
}
cout<<res;
}
7、HJ5 进制转换
#include<iostream>
#include<math.h>
#include<string>
using namespace std;
int main(){
string s; //0xAA
cin>>s;
// 方法一:cout<<stoi(s,0,16)<<endl;
int n=s.size();
int res=0;
// 从后向前遍历,0x不用转换,忽略即可
for(int i=n-1;i>1;i--)
{
int cur=0;
// 如果当前数是0-9,则res+=n^(n-i-1)
if(s[i]>='0'&&s[i]<='9'){
cur=s[i]-'0';
}
// 如果当前数是A-F,则res+=n^(n-i-1)
if(s[i]>='A'&&s[i]<='F'){
cur=s[i]-'A'+10;
}
res+=cur*pow(16,n-i-1);
}
cout<<res<<endl;
return 0;
}
8、HJ80 整型数组合并
#include<bits/stdc++.h>
using namespace std;
int main(){
// 获取输入
int n1,n2,tmp;
vector<int> s1;
vector<int> s2;
cin>>n1;
while(n1--){
cin>>tmp;
s1.push_back(tmp);
}
cin>>n2;
while(n2--){
cin>>tmp;
s2.push_back(tmp);
}
// 将2个数组排序下
sort(s1.begin(), s1.end());
sort(s2.begin(), s2.end());
// 同时合并两个有序数组
string res;
int i=0;
int j=0;
unordered_set<int> set;//哈希集合,用来去重
while(i<s1.size()&&j<s2.size()){
// 谁小添加谁
if(s1[i]<=s2[j]) {
// 如果之前集合中没有才添加,保证不会有重复的
if(!set.count(s1[i])){
set.insert(s1[i]);
res+=to_string(s1[i]);
}
i++;
}
else if(s1[i]>s2[j]){
// 如果之前集合中没有才添加,保证不会有重复的
if(!set.count(s2[j])){
set.insert(s2[j]);
res+=to_string(s2[j]);
}
j++;
}
}
while(i<s1.size()){
// 如果之前集合中没有才添加,保证不会有重复的
if(!set.count(s1[i])){
set.insert(s1[i]);
res+=to_string(s1[i]);
}
i++;
}
while(j<s2.size()){
// 如果之前集合中没有才添加,保证不会有重复的
if(!set.count(s2[j])){
set.insert(s2[j]);
res+=to_string(s2[j]);
}
j++;
}
cout<<res<<endl;
return 0;
}
四、字符串篇(13)
1、HJ46 截取字符串
#include<iostream>
#include<string>
using namespace std;
int main(){
// 获取输入
string s;
getline(cin,s);
int k;
cin>> k;
// 返回结果
cout<<s.substr(0,k);
return 0;
}
2、HJ34 图片整理
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main(){
// 获取输入
string s;
getline(cin, s);
// 排序
sort(s.begin(), s.end());
cout <<s;
return 0;
}
3、HJ14 字符串排序
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
// 获取输入
string s;
int k;
cin>>k;
vector<string> arr;
while(k--){
cin>>s;
arr.push_back(s);
}
sort(arr.begin(),arr.end());
for(int i=0;i<arr.size();i++){
cout<<arr[i]<<endl;
}
return 0;
}
4、HJ12 字符串反转
#include<iostream>
#include<string>
using namespace std;
int main(){
// 获取输入
string s;
getline(cin,s);
// 计算结果
int i=0;
// 从最后一个字符向前走
int j=s.length()-1;
while(i<j){
swap(s[i++],s[j--]);
}
cout<<s;
return 0;
}
5、HJ106 字符逆序
#include <iostream>
#include <string>
using namespace std;
void reverseStr(string &str,int start,int end){
int left=start;
int right=end;
while(left<right) swap(str[left++],str[right--]);
}
int main(){
// 获取输入
string s;
getline(cin, s);
reverseStr(s,0,s.length()-1);
cout<<s;
}
6、HJ1 字符串最后一个单词的长度
#include<iostream>
#include<string>
using namespace std;
int main(){
// 获取输入
string input;
getline(cin,input);
// 计算结果
int res=0;
// 从最后一个字符向前走
int i=input.length()-1;
while(i>=0&&input[i]!=' '){
res++;
i--;
}
cout<<res;
return 0;
}
7、HJ4 字符串分隔
#include<iostream>
#include<string>
using namespace std;
int main(){
// 获取输入
string str;
while(cin >> str){
int len = str.size();
// 如果字符串不是8的倍数,在字符串后添加count个'0'
if (len % 8 != 0){
int count = 8 - len % 8;
str.append(count, '0');
}
// 此时字符串一定是8的倍数,每8个字符输出即可
int newLen = str.size();
for (int i = 0; i < newLen; i += 8){
cout << str.substr(i, 8) << endl;
}
}
return 0;
}
8、HJ21 简单密码
#include<bits/stdc++.h>
using namespace std;
int main(){
// 获取输入
string s;
getline(cin,s);
// 处理字符串
vector<pair<string,int>> arr;
for(int i=0;i<s.length();++i){
if(s[i]>='A'&&s[i]<='Z'){
if(s[i]=='Z') s[i]='a';
else {
s[i]=tolower(s[i]+1);
}
}
else if(s[i]>='a'&&s[i]<='c'){
s[i]='2';
}
else if(s[i]>='d'&&s[i]<='f'){
s[i]='3';
}
else if(s[i]>='g'&&s[i]<='i'){
s[i]='4';
}
else if(s[i]>='j'&&s[i]<='l'){
s[i]='5';
}
else if(s[i]>='m'&&s[i]<='o'){
s[i]='6';
}
else if(s[i]>='p'&&s[i]<='s'){
s[i]='7';
}
else if(s[i]>='t'&&s[i]<='v'){
s[i]='8';
}
else if(s[i]>='w'&&s[i]<='z'){
s[i]='9';
}
}
cout<<s<<endl;
return 0;
}
9、HJ13 句子逆序
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
void reverseStr(string &str,int start,int end){
int left=start;
int right=end;
while(left<right) swap(str[left++],str[right--]);
}
void split(string &str){
int left=0;
int len=str.length();
while(left<len){
while(left<len&&str[left]==' ') left++;
int right=left;
while(right<len&&str[right]!=' ')right++;
reverseStr(str,left,right-1);
left=right;
}
}
int main(){
// 获取输入
string s;
while(getline(cin, s)){
split(s);
reverse(s.begin(), s.end());
cout <<s;
}
}
10、HJ31 单词倒排
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
void reverseStr(string &str,int start,int end){
int left=start;
int right=end;
while(left<right) swap(str[left++],str[right--]);
}
bool is_A(char c){
if(c>='A'&&c<='Z') return true;
return false;
}
bool is_a(char c){
if(c>='a'&&c<='z') return true;
return false;
}
void split(string &str){
int left=0;
int len=str.length();
while(left<len){
while(left<len&&str[left]==' ') left++;
int right=left;
while(right<len&&str[right]!=' ')right++;
reverseStr(str,left,right-1);
left=right;
}
}
// 将所有的非字母字符替换为空格
void update(string &str){
for(int i=0;i<str.size();i++){
if(!is_A(str[i])&&!is_a(str[i])) str[i]=' ';
}
}
int main(){
// 获取输入
string s;
while(getline(cin, s)){
update(s);
split(s);
reverse(s.begin(), s.end());
cout <<s;
}
return 0;
}
11、HJ85 最长回文子串
#include<bits/stdc++.h>
#include<cmath>
using namespace std;
// 判断是否是回文子串
bool is_true(string & s){
int left=0;
int right=s.length()-1;
while(left<=right){
if(s[left++]!=s[right--]) return false;
}
return true;
}
int main(){
// 获取输入
string s;
getline(cin, s);
//定义动态数组
int len=s.length();
int res=0;
for(int i=0;i<len;i++){
for(int j=1;j<len-i+1;j++){
string str=s.substr(i,j);
//cout<<str<<endl;
if(is_true(str)&&res<str.length()) res=str.length();
}
}
cout<<res<<endl;
return 0;
}
12、HJ87 密码强度等级
#include<bits/stdc++.h>
using namespace std;
int main(){
// 获取输入
string s;
getline(cin,s);
// 计算分数
int score=0;
// 检查长度
int len=s.length();
if(len<=4) score+=5;
else if(len<=7) score+=10;
else if(len>=8) score+=25;
// 统计字母、数字、符号的个数
int alpha_A=0;
int alpha_a=0;
int digit=0;
int other=0;
for(char c:s){
if(isdigit(c))digit++;
else if(c>='a'&&c<='z')alpha_a++;
else if(c>='A'&&c<='Z')alpha_A++;
else other++;
}
//cout<<alpha_A<<alpha_a<<digit<<other;
//检查字母
if(alpha_A==0&&alpha_a==0) score+=0;
else if(alpha_A==0||alpha_a==0) score+=10;
else if(alpha_A>0||alpha_a>0)score+=20;
//cout<<score;
// 检查数字
if(digit==0) score+=0;
else if(digit==1) score+=10;
else if(digit>1)score+=20;
//cout<<score;
// 检查符号
if(other==0) score+=0;
else if(other==1) score+=10;
else if(other>1)score+=25;
//cout<<score;
// 检查奖励
int n=0;
if((alpha_a>0||alpha_A>0)&&digit>0) n=3;
if((alpha_a>0||alpha_A>0)&&digit>0&&other>0) n=3;
if(alpha_a>0&&alpha_A>0&&digit>0&&other>0)n=5;
score+=n;
//cout<<score;
// 输出结果
if(score>=90) cout<<"VERY_SECURE"<<endl;
else if(score>=80) cout<<"SECURE"<<endl;
else if(score>=70) cout<<"VERY_STRONG"<<endl;
else if(score>=60) cout<<"STRONG"<<endl;
else if(score>=50) cout<<"AVERAGE"<<endl;
else if(score>=25) cout<<"WEAK"<<endl;
else if(score>=0) cout<<"VERY_WEAK"<<endl;
return 0;
}
13、HJ96 表示数字
#include<bits/stdc++.h>
using namespace std;
int main(){
// 获取输入
string s;
cin>>s;
// 处理字符串
for(int i = 0; i < s.length(); i++){
if(isdigit(s[i])){ // 每次第一个遇到的数字前加*
s.insert(i, "*");
i++;
while(isdigit(s[i])) //遍历连续的数字找到这一段的最后一个数字
i++;
s.insert(i, "*"); //最后加*
}
}
// 输出结果
cout << s << endl;
return 0;
}
五、链表篇(1)
1、HJ51 输出单向链表中倒数第k个结点
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
struct ListNode
{
int m_nKey;
ListNode* m_pNext;
ListNode(int val){m_nKey=val;m_pNext=nullptr;}
};
int main(){
// 获取输入
int n;
ListNode* myCode= new ListNode(0);
while(cin>>n){
int tmp=0;
ListNode* p=myCode;// 非常重要,遍历指针法
while(n--){
cin>>tmp;
//创建单链表
ListNode* newCode= new ListNode(tmp);
p->m_pNext=newCode;
p=p->m_pNext;
}
// 获取k
cin>>tmp;
ListNode* left=myCode->m_pNext;
ListNode* right=myCode->m_pNext;
while(tmp--) {
right=right->m_pNext;
}
while(right){
left=left->m_pNext;
right=right->m_pNext;
}
cout<<left->m_nKey<<endl;
}
}
六、递归篇(2)
1、HJ37 统计每个月兔子的总数
#include <bits/stdc++.h>
using namespace std;
/*斐波那契数列:1:1 2:1 3:2 4:3 5:5 6:8*/
int getSum(int n) { //求每个月兔子数
if(n == 1 || n == 2) //n=1或2跳出递归
return 1;
return getSum(n - 1) + getSum(n - 2); //返回前两个月相加
}
int main(){
// 获取输入
int n;
cin>>n;
// 输出结果
int res;
res=getSum(n);
cout<<res;
}
2、HJ61 放苹果
#include<bits/stdc++.h>
using namespace std;
// 把m个苹果放在n个盘子里的分法
int f(int m,int n){
// 如果只有1个盘子或者苹果数为0,则只有一种分法
if(m==0 || n==1)
return 1;
// 如果n>m,则必定有n-m个盘子永远空着,去掉它们对摆放苹果方法数目不产生影响。即if(n>m) f(m,n) = f(m,m)
else if(n>m)
return f(m,m);
// 如果n<=m,则盘子数比苹果数少
else
/* 存在如下2种情况:
1、有至少一个盘子空着,则可以拿走这个盘子,即相当于f(m,n) = f(m,n-1);
2、所有盘子都有苹果,相当于可以从每个盘子中拿掉一个苹果,不影响不同放法的数目,即f(m,n) = f(m-n,n).
而总的放苹果的放法数目等于两者的和,即 f(m,n) =f(m,n-1)+f(m-n,n)
*/
return f(m,n-1)+f(m-n,n);// 把m个苹果放在n-1个盘子里的分法
}
int main(){
// 获取输入
int m,n;
cin>>m>>n;
// 输出结果
cout << f(m,n) << endl;
}
七、模拟篇(3)
1、HJ35 蛇形矩阵
#include <bits/stdc++.h>
using namespace std;
int main(){
// 获取输入
int n;
cin>>n;
// 间隔变,计算各个数字
int beg=1;// 每行的开始数字
for(int i=1;i<=n;i++)
{
cout<<beg;
int tmp = beg;// 每行中的数
for(int j=i+1;j<=n;j++)
{
tmp+=j;
cout<<" "<<tmp;
}
cout<<endl;
beg+=i;
}
}
2、HJ83 二维数组操作
#include<bits/stdc++.h>
using namespace std;
/*这道题不需要实现表格功能,只要满足对应的输入输出即可*/
int main(){
int m,n; //数据表的行数和列数
while(cin>>m>>n) { //输入数据表的行数和列数
// 初始化表格
if(m>9 || n>9) //如果行数或者列数大于9,返回-1,否则返回0
cout<<-1<<endl;
else
cout<<0<<endl;
// 交换2个坐标
int x1,y1,x2,y2; //(x1,y1)(x2,y2)为两个坐标
cin>>x1>>y1>>x2>>y2; //分别输入x1,y1,x2,y2的值
if(x1>=m || y1>=n || x2>=m || y2>=n) //如果行坐标的值大于等于数据表的行数;或者列坐标的值大于等于数据表的列数,那么返回-1,否则返回0
cout<<-1<<endl;
else
cout<<0<<endl;
// 在row上添加一行
int row; //row为行号
cin>>row; //输入行号
if(row<0 && row>=m || m==9) //如果行号大于数据表的行数,或者数据表的行数为9,则返回-1,否则返回0
cout<<-1<<endl;
else
cout<<0<<endl;
// 在column左边添加一列
int column; //row为列号
cin>>column; //输入列号
if(column<0 || column>=n || n==9) //如果列号大于数据表的列数,或者数据表的列数为9,则返回-1,否则返回0
cout<<-1<<endl;
else
cout<<0<<endl;
// 查询x和y的坐标值
int x,y; //(x,y)为坐标
cin>>x>>y; //输入x和y的值
if(x<0 || x>=m || y<0 || y>=n) //如果行坐标的值大于等于数据表的行数;或者列坐标的值大于等于数据表的列数,那么返回-1,否则返回0
cout<<-1<<endl;
else
cout<<0<<endl;
}
return 0;
}
3、HJ22 汽水瓶
#include<bits/stdc++.h>
using namespace std;
/*
方法一:观察规律
注意到每两个空汽水瓶就可以通过借一个空汽水瓶来喝到一瓶汽水,
故最多可以喝到的汽水瓶数等于空汽水瓶数除以二,即 sum = num / 2
方法二:
n>=2时才有可能喝到汽水,只要手上的空汽水瓶数大于或等于2,不论情况如何,先借一个空汽水瓶
*/
int main(){
int num;
while(cin>>num){
if(num==0) break;// 0表示输入结束,不用处理
int sum = 0; //计数器,最多可以喝的汽水瓶数
// 空汽水瓶数大于或等于 2 时,至少可以喝到一瓶汽水,如通过“先借后还”方式就可以喝到汽水
while (num >= 2)
{
num += 1; //只要手上的空汽水瓶数大于或等于2,不论情况如何,先借一个空汽水瓶
int count = num / 3; //一次空汽水瓶换汽水操作后可以喝到的汽水瓶数(3 个空汽水瓶换 1 瓶汽水,喝它!)
num = num % 3 + count - 1; //剩下的空汽水瓶数,包括之前没换的空汽水瓶 + 喝完汽水后的空汽水瓶 + 要还回去空汽水瓶(之前借了一个空汽水瓶);
sum += count; //累计可以喝到的汽水瓶数
}
cout<<sum<<endl;
}
return 0;
}
八、动态规划篇(1)
1、HJ91 走方格的方案数
(1)递归法
#include<bits/stdc++.h>
using namespace std;
// f(n,m)表示从[0,0]到[n-1,m-1]的走法数
int f(int n,int m){
if(n==0||m==0) return 1;// 当处于第一列或第一行时,明显只有一种走法
return f(n-1,m)+f(n,m-1);
}
int main(){
// 获取输入
int n,m;
cin>>n>>m;
cout<<f(n,m)<<endl;
return 0;
}
(2)动态规划法
#include<bits/stdc++.h>
using namespace std;
/* 解析:本类型题是网格路径问题,可以看做是二维版本的爬楼梯问题
【状态定义】:dp[i][j] 表示的含义为从[0,0]到[i-1,j-1]的走法数
【转移方程】:[i,j]只能是从上一格[i,j-1]或者左一格[i-1,j]达到
所以dp[i][j]=dp[i][j-1]+dp[i-1][j];
*/
int main(){
// 获取输入
int n,m;
cin>>n>>m;
//定义动态数组
vector<vector<int>> dp(n + 1,vector<int>(m + 1,0)) ;
for(int i=0;i<=n;i++) dp[i][0]=1;
for(int i=0;i<=m;i++) dp[0][i]=1;
// 遍历[1,1]到[n,m]
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
dp[i][j] =dp[i-1][j]+dp[i][j - 1];
}
}
cout<<dp[n][m]<<endl;
return 0;
}
九、栈篇(1)
1、HJ54 表达式求值
#include<iostream>
#include<stack>
using namespace std;
void compute(stack<int>& st1, stack<char>& st2){ //根据栈顶运算符弹出栈顶两个元素进行运算
int b = st1.top();
st1.pop();
int a = st1.top();
st1.pop();
char op = st2.top(); //栈顶运算符
st2.pop();
if(op == '+') a = a + b; //加
else if(op == '-') a = a - b; //减
else if(op == '*') a = a * b; //乘
else if(op == '/') a = a / b; //除
st1.push(a);
}
bool priority(char m, char n){ //比较运算符优先级
if(m == '(') //括号优先级最高
return false;
else if((m == '+' || m == '-') && (n == '*' || n == '/')) //加减法小于乘除法
return false;
return true;
}
int main(){
string s;
while(cin >> s){
stack<int> st1; //记录运算数字
stack<char> st2; //记录运算符
st2.push('('); //整个运算式添加括号
s += ')';
bool flag = false;
for(int i = 0; i < s.length(); i++){
if(s[i] == '(') //如果是左括号都在运算符栈加入(
st2.push('(');
else if(s[i] == ')'){ //遇到右括号
while(st2.top() != '('){ //弹出开始计算直到遇到左括号
compute(st1, st2);
}
st2.pop(); //弹出左括号
} else if(flag){ //运算符
while(priority(st2.top(), s[i])){ //比较运算优先级
compute(st1, st2); //可以直接计算
}
st2.push(s[i]); //需要将现阶段加入栈中等待运算
flag = false;
} else{ //数字
int j = i; //记录起始
if(s[j] == '-' || s[j] == '+') //正负号
i++;
while(isdigit(s[i])){
i++;
}
string temp = s.substr(j, i - j);
st1.push(stoi(temp)); //截取数字部分,转数字
i--;
flag = true; //数字结束,下一次flag为true就是运算符了
}
}
cout << st1.top() << endl; //输出
}
return 0;
}