华为机试在线训练
- 0.基础知识
- 1.入门题
- 简单题
- HJ11 数字颠倒 字符串 简单 55.18%
- HJ12 字符串反转 字符串 简单 55.29%
- HJ22 汽水瓶 模拟 简单 26.35%
- ⭐HJ37 统计每个月兔子的总数 排序 简单 39.23%
- ⭐⭐⭐HJ50 四则运算 字符串栈数学 简单 53.71%
- ⭐HJ53 杨辉三角的变形 字符串 简单 48.69%
- ⭐⭐星星HJ54 表达式求值 字符串数学栈 简单 52.83%
- HJ56 iNOC产品部--完全数计算 数学 简单 45.75%
- ⭐HJ61 放苹果 递归动态规划 简单 44.67%
- HJ62 查找输入整数二进制中1的个数 位运算 简单 47.32%
- HJ66 配置文件恢复 字符串 简单 42.32%
- HJ72 百钱买百鸡问题 简单 45.02%
- HJ73 计算日期到天数转换 字符串 简单 40.22%
- ⭐HJ74 参数解析 字符串 简单 35.64%
- HJ75 ⭐公共字串计算 字符串 简单 39.13%
- HJ76 尼科彻斯定理 数学 简单 42.94%
- HJ83 二维数组操作 数组 简单 27.33%
- HJ84 统计大写字母个数 字符串 简单 39.97%
- HJ85 最长回文子串 字符串穷举 简单 37.98%
- HJ86 求最大连续bit数 位运算 简单 40.91%
- HJ87 密码强度等级 字符串 简单 30.95%
- ▲HJ91 走方格的方案数 字符串 简单 43.14%
- HJ97 记负均正 数组 简单 19.34%
- HJ100 等差数列 数学 简单 38.17%
- HJ106 字符逆序 字符串 简单 42.93%
- HJ108 求最小公倍数 递归 数学
- 中等题
- HJ5 进制转换 字符串 中等 30.33%
- ⭐HJ6 质数因子 排序 中等 25.93%
- HJ8 合并表记录 中等 32.99%
- HJ9 提取不重复的整数 数组哈希位运算 中等 40.27%
- HJ10 字符个数统计 字符串哈希 中等 43.31%
- HJ14 字符串排序 字符串 中等 38.08%
- HJ16 购物单 动态规划 中等 19.61%
- HJ21 简单密码破解 字符串 中等 38.27%
- HJ26 字符串排序 排序字符串 中等 33.56%
- HJ34 图片整理 字符串 中等 42.77%
- HJ35 蛇形矩阵 数组 中等 39.60%
- HJ36 字符串加密 字符串 中等 37.67%
- HJ38 求小球落地5次后所经历的路程和第5次反弹的高度 模拟 中等 35.11%
- HJ40 输入一行字符,分别统计出包含英文字母、空格、数字和其它字符的个数 字符串 中等 40.13%
- ⭐⭐⭐HJ43 迷宫问题 排序 中等 33.63%
- HJ45 名字的漂亮度 字符串 中等 34.29%
- HJ46 按字节截取字符串 字符串 中等 41.95%
- ⭐⭐HJ48 从单向链表中删除指定值的节点 链表 中等 34.81%
- ⭐⭐⭐HJ52 计算字符串的距离 字符串 中等 37.26%
- HJ55 挑7 穷举数学 中等 40.47%
- HJ57 高精度整数加法 字符串 中等 35.87%
- HJ59 找出字符串中第一个只出现一次的字符 字符串 中等 30.02%
- HJ60 查找组成一个偶数最接近的两个素数 穷举数学 中等 41.17%
- HJ63 DNA序列 字符串 中等 39.37%
- HJ64 MP3光标位置 数组 中等 29.67%
- HJ65 查找两个字符串a,b中的最长公共子串 字符串 中等 33.79%
- ⭐⭐⭐HJ67 24点游戏算法 搜索dfs 中等 34.66%
- HJ69 矩阵乘法 数组 中等 40.92%
- HJ70 矩阵乘法计算量估算 字符串 中等 38.65%
- HJ71 字符串通配符 字符串 中等 30.60%
- ▲HJ88 扑克牌大小 字符串队列链表栈 中等 32.57%
- HJ90 合法IP 字符串链表栈队列 中等 35.19%
- HJ96 表示数字 字符串 中等 30.72%
- ⭐⭐⭐HJ98 自动售货系统 字符串 中等 25.15%
- ⭐HJ99 自守数 中等 35.34%
- HJ102 字符统计 字符串排序 中等 28.64%
- ⭐J103 Redraiment的走法 排序 中等 26.53%
- ⭐⭐⭐HJ107 求解立方根 数学二分 中等 27.30%
- 较难题
- HJ1 字符串最后一个单词的长度 字符串 较难 29.61%
- HJ2 计算字符个数 字符串哈希 较难 28.00%
- ⭐HJ3 明明的随机数 数组 较难 19.88%
- HJ4 字符串分隔 字符串 较难 26.23%
- HJ13 句子逆序 数组 较难 36.49%
- ⭐⭐HJ24 合唱队 队列动态规划 较难 24.42%
- HJ29 字符串加解密 字符串 较难 25.10%
- HJ30 字符串合并处理 字符串排序 较难 25.02%
- HJ32 密码截取 字符串 较难 26.13%
- ⭐⭐HJ33 整数与IP地址间的转换 字符串 较难 28.65%
- ⭐HJ42 学英语 字符串 较难 28.37%
- HJ58 输入n个整数,输出其中最小的k个 数组 较难 30.11%
- HJ80 整型数组合并 数组排序 较难 30.46%
- HJ81 字符串匹配 字符串 较难 28.11%
- HJ92 在字符串中找出连续最长的数字串 字符串 较难 27.75%
- HJ94 记票统计 较难 26.11%
- HJ23 删除字符串中出现次数最少的字符 字符串
- 🔺HJ89 24点运算 字符串模拟穷举 困难 20.12%
- HJ31 单词倒排 字符串排序 困难 19.80%
0.基础知识
0.1.输入输出
0.1.1基础输入输出
- 输入正常普通的
int n;
cin>>n;
cout<<n;
- 输入带空格的
string str;
cin(cin,str);
0.1.2 头文件
- 通用头文件
#include<bits/stdc++.h>
using namespace std;
0.1.2输出一位小数
printf("%.1f\n",ans);
0.2.关于字符串的常见操作
substr
string str='123';
string temp=str.substr(0,1);
//substr(开始的位置,长度) substr(begin_index,length)
atoi
string temp='123';
int temp_int=atoi(temp.c_str());
//注意使用c_str()
to_string
int num = 123;
string num_str = to_string(num);
uppercase
transform(str.begin(),str.end(),str.begin(),toupper);
遍历ASCII码
for(char i=0;i<127;i++)
if(map[char(i)]) count++;
find()
string s1 = to_string(i);
string s2 = to_string(j);
int pos = s2.size()- s1.size();
if(s2.find(s1,pos) != -1)
//从pos找字符串为s1的的下标
//可以单纯找s1 s2.find(s1)
0.3.关于vector的常见操作
⭐set操作,自动排序去重
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
set<int> record;
while(n--)
{
int num;
cin>>num;
record.insert(num);//--------------------------------------------
//if(find(record.begin(),record.end())==record.end())record.push_back(num);
}
set<int>::iterator it;
for(it=record.begin();it!=record.end();it++)//--------------------------------------------
cout<<*it<<endl;
}
return 0;
}
⭐二维数组
vector<vector<int>> dp(n+1,vector<int>(m+1,1));
0.4.关于动态规划
- 子序列并不一定是连续的子串
- 子串一定是连续的
- 连续递增的子序列和前一个字符的最大递增长度
int longest[len];
for (int i = 0; i < len; i++) {
longest[i] = 1;
}
for (int j = 1; j < len; j++) {
for (int i = 0; i < j; i++) {
if (arr[j] > arr[i] && longest[j] < longest[i] + 1) {// 注意longest[j] 小于 longest[i]+1 不能省略
longest[j] = longest[i] + 1;// 计算以arr[j]结尾的序列的最长递增子序列的长度
}
}
}
1.入门题
HJ7 取近似值
HJ7 取近似值
写出一个程序,接受一个正浮点数值,输出该数值的近似整数值。如果小数点后数值大于等于5,向上取整;小于5,则向下取整。
输入一个正浮点数值
输出该数值的近似整数值 5.5-6
#include<bits/stdc++.h>
using namespace std;
int main()
{
float n;
cin>>n;
cout<<(int(n+0.5))<<endl;
return 0;
}
HJ15 求int型正整数在内存中存储时1的个数
HJ15 求int型正整数在内存中存储时1的个数
输入一个int型的正整数,计算出该int型数据在内存中存储时1的个数。
输入一个整数(int类型)
这个数转换成2进制后,输出1的个数
—————————————————————————————————————————————————————————————
解法:
- 将十进制数转化成二进制数,先取模,然后除2,得到1的个数,最后不断除二会变成0,就是最终的判断条件
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
int count=0;
while(n)
{
if(n%2)count++;
n=n/2;
}
cout<<count<<endl;
return 0;
}
—————————————————————————————————————————————————————
HJ101 输入整型数组和排序标识,对其元素按照升序或降序进行排序
HJ101 输入整型数组和排序标识,对其元素按照升序或降序进行排序
解题:
- 处理输入输出
- 找出空格所在的位置,并对字符串进行提取,转换成数字;其中第一个数字要特殊处理,最后一个也要特殊处理(可以通过将字符串长度推入假设为空格位置也可以切分)。
- 完成排序
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
string str1;
getline(cin,str1);
string str;
getline(cin,str);
int index;
cin>>index;
vector<int> blank;
//找出所有空格的位置
for(int i=0;i<str.length();i++)
if(str[i]==' ') blank.push_back(i);
blank.push_back(str.length());
//提取出每个数字所在的地方,第一个数字特殊处理,最后一个数字也是,主动输入最后一个位置要处理的长度
vector<int> answer;
string temp =str.substr(0,blank[0]);
int temp_int=atoi(temp.c_str());
answer.push_back(temp_int);
for(int i=1;i<blank.size();i++)
{
string temp=str.substr(blank[i-1]+1,blank[i]-blank[i-1]-1);
answer.push_back(atoi(temp.c_str()));//注意这里要加c_str才能正常转换
}
//排序
sort(answer.begin(),answer.end());
if(index) reverse(answer.begin(),answer.end());
//处理输出
for(int i=0;i<answer.size();i++) cout<<answer[i]<<' ';
cout<<endl;
}
return 0;
}
简单题
HJ11 数字颠倒 字符串 简单 55.18%
HJ11 数字颠倒添加链接描述
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
string str=to_string(n);
reverse(str.begin(),str.end());
cout<<str<<endl;
return 0;
}
HJ12 字符串反转 字符串 简单 55.29%
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
getline(cin,str);
reverse(str.begin(),str.end());
cout<<str<<endl;
return 0;
}
HJ22 汽水瓶 模拟 简单 26.35%
HJ22 汽水瓶
题解:只要有两瓶水就可以额外喝一瓶饮料
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
while(cin>>n&&n!=0)
{
int count=0;
while(n>=2)
{
count++;
n-=2;
}
cout<<count<<endl;
}
return 0;
}
⭐HJ37 统计每个月兔子的总数 排序 简单 39.23%
没考虑好
#include<bits/stdc++.h>
using namespace std;
//斐波那契数列函数
int getTotalCount(int monthCount)
{
int F[monthCount + 1];
F[0] = 1; //第一个月的兔子数,小兔子出生,然后开始长大。
F[1] = 1; //第二个月的兔子数,小兔子继续长大,慢慢变成老兔子。
F[2] = 2; //第三个月的兔子数,老兔子开始生小兔子了。后面出生的小兔子则与老兔子类似。
for(int i = 3; i < monthCount; i++)
{
F[i] = F[i-1] + F[i-2];
}
//返回第 monthCount 个月的兔子总数
return F[monthCount - 1];
}
//主函数,调用斐波那契数列函数的接口来得到每个月的兔子总数
int main()
{
int monthCount;
while(cin >> monthCount)
{
cout << getTotalCount(monthCount) << endl;
}
return 0;
}
⭐⭐⭐HJ50 四则运算 字符串栈数学 简单 53.71%
题解:
- 使用双栈,将数字和符号分开存储
- 遇到左括号,=-*/先压入栈,计算的情况由两种
- 一是遇到右括号时,开始对数字进行计算,每次使用一个符号,两个数字,计算出来的数字再压入栈
- 二是遇到要压入栈的符号,是同级优先度,或者的优先度大于
#include<bits/stdc++.h>
using namespace std;
stack<int> num;
stack<char> op;
void eval()
{
auto b = num.top(); num.pop();
auto a = num.top(); num.pop();
auto c = op.top(); op.pop();
int x;
if (c == '+') x = a + b;
else if (c == '-') x = a - b;
else if (c == '*') x = a * b;
else x = a / b;
num.push(x);
}
int main()
{
//1.形成优先级,乘除大于加减
unordered_map<char, int> pr{{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};
//2.读入字符串
string str;
cin>>str;
//3.将所有括号统一成小括号
for(int i=0;i<str.size();i++)
{
if(str[i]=='{') str[i]='(';
if(str[i]=='}') str[i]=')';
if(str[i]==']') str[i]=')';
if(str[i]=='[') str[i]='(';
}
//4.判断是负数还是是减号的标志位
bool flag=false;
for (int i = 0; i < str.size(); i ++ )
{
//读取字符
auto c = str[i];
//如果是数字
if (isdigit(c))
{
//5.读入数字,如果是大于9的也进行处理
int x = 0, j = i;
while (j < str.size() && isdigit(str[j]))
x = x * 10 + str[j ++ ] - '0';
i = j - 1;
//6.判断是负数还是是减号,判断压入栈的数字正负
flag?num.push(-x):num.push(x);
flag=false;
}
else if (c == '(') op.push(c);//7.如果是左括号压入栈
else if (c == ')')//8.如果是右括号,进行处理中间出现的=-*/
{
while (op.top() != '(') eval();//8.1一直处理到见到左括号为止
op.pop();//8.2将左括号pop
}
//9.判断负数
else if(c=='-' && i-1>0 && str[i-1]=='(' && i+1<str.size() && isdigit(str[i+1]))
{
flag=true; //标记负数
}
else //10.判断加减乘除,如果输入的是乘除,先压入栈,如果是加减,先将内部的加减乘除运算完
{
while (op.size() && pr[op.top()] >= pr[c]) eval();
op.push(c);//压入符号
}
}
while (op.size()) eval();//11.如果还有符号,继续运算
cout<< num.top()<<endl;//12.输出最终的数字
return 0;
}
//模拟3+2*{1+2*[-4/(8-6)+7]}
//1.----------------------------------------------
//op + * ( + * ( / ( - )
//num 3 2 1 2 -4 8 6
//2.----------------------------------------------
//op + * ( + * ( +
//num 3 2 1 2 -2
//3.----------------------------------------------
//op + * ( + * ( + )
//num 3 2 1 2 -2 7
//4.----------------------------------------------
//op + * ( + *
//num 3 2 1 2 5
//5.----------------------------------------------
//op + * ( +
//num 3 2 1 10
//6.----------------------------------------------
//op + *
//num 3 2 11
//7.----------------------------------------------
//op +
//num 3 22
//8.----------------------------------------------
//op
//num 25
//------------------------------------------------
⭐HJ53 杨辉三角的变形 字符串 简单 48.69%
本题是找规律的题,只要往下再写几行就可以看出奇偶的规律,而且每行只需要写前几个就可以了,因为题目问的是第一个偶数的index。
于是我们会发现,只有n为1,2时,没有出现偶数,剩下的按照2 3 2 4的规律每四行循环一次。
没看出来。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int input;
int result;
int tmp[4] = {2,3,2,4};
while(cin>>input)
{
if(input == 1||input == 2)
result = -1;
else
result = tmp[(input -3)%4];
cout << result <<endl;
}
return 0;
}
⭐⭐星星HJ54 表达式求值 字符串数学栈 简单 52.83%
四则运算翻版,加一个判断第一个数字是不是负数的就可以了
#include<bits/stdc++.h>
using namespace std;
stack<int> num;
stack<char> op;
void eval()
{
auto b = num.top(); num.pop();
auto a = num.top(); num.pop();
auto c = op.top(); op.pop();
int x;
if (c == '+') x = a + b;
else if (c == '-') x = a - b;
else if (c == '*') x = a * b;
else x = a / b;
num.push(x);
}
int main()
{
//1.形成优先级,乘除大于加减
unordered_map<char, int> pr{{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};
//2.读入字符串
string str;
cin>>str;
//3.将所有括号统一成小括号
for(int i=0;i<str.size();i++)
{
if(str[i]=='{') str[i]='(';
if(str[i]=='}') str[i]=')';
if(str[i]==']') str[i]=')';
if(str[i]=='[') str[i]='(';
}
//4.判断是负数还是是减号的标志位
bool flag=false;
for (int i = 0; i < str.size(); i ++ )
{
//读取字符
auto c = str[i];
//如果是数字
if (isdigit(c))
{
//5.读入数字,如果是大于9的也进行处理
int x = 0, j = i;
while (j < str.size() && isdigit(str[j]))
x = x * 10 + str[j ++ ] - '0';
i = j - 1;
//6.判断是负数还是是减号,判断压入栈的数字正负
flag?num.push(-x):num.push(x);
flag=false;
}
else if (c == '(') op.push(c);//7.如果是左括号压入栈
else if (c == ')')//8.如果是右括号,进行处理中间出现的=-*/
{
while (op.top() != '(') eval();//8.1一直处理到见到左括号为止
op.pop();//8.2将左括号pop
}
//9.判断负数
else if(c=='-' && i-1>0 && str[i-1]=='(' && i+1<str.size() && isdigit(str[i+1]))
{
flag=true; //标记负数
}//处理负数出现在开头的位置
else if(c=='-'&&i==0&&i+1<str.size()&&isdigit(str[i+1]))
{
flag=true;
}
else //10.判断加减乘除,如果输入的是乘除,先压入栈,如果是加减,先将内部的加减乘除运算完
{
while (op.size() && pr[op.top()] >= pr[c]) eval();
op.push(c);//压入符号
}
}
while (op.size()) eval();//11.如果还有符号,继续运算
cout<< num.top()<<endl;//12.输出最终的数字
return 0;
}
HJ56 iNOC产品部–完全数计算 数学 简单 45.75%
题解:根据题意写
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
int sum=0;
for(int i=2;i<=n;i++)
{
int count=1;
for(int j=2;j<=i/2;j++)
{//乘数不会超过i的一半
if(i%j==0) count+=j;
}
if(count==i)sum++;
}
cout<<sum<<endl;
}
}
⭐HJ61 放苹果 递归动态规划 简单 44.67%
/*
放苹果分为两种情况,一种是有盘子为空,一种是每个盘子上都有苹果。
令(m,n)表示将m个苹果放入n个盘子中的摆放方法总数。
1.假设有一个盘子为空,则(m,n)问题转化为将m个苹果放在n-1个盘子上,即求得(m,n-1)即可
2.假设所有盘子都装有苹果,则每个盘子上至少有一个苹果,即最多剩下m-n个苹果,问题转化为将m-n个苹果放到n个盘子上
即求(m-n,n)
*/
#include<bits/stdc++.h>
using namespace std;
int f(int m,int n){
if(m<0||n<0) return 0;
else if(m==1||n==1) return 1;
else if(n<m) return f(m,n-1)+f(m-n,n);
}
int main(){
int m,n;
while(cin >> m >> n){
cout << f(m,n) << endl;
}
return 0;
}
HJ62 查找输入整数二进制中1的个数 位运算 简单 47.32%
题解:使用位运算很简单
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
int sum=0;
while(n)
{
sum+=n%2;
n=n>>1;
}
cout<<sum<<endl;
}
}
HJ66 配置文件恢复 字符串 简单 42.32%
题解见注释
#include<bits/stdc++.h>
using namespace std;
//处理输入输出
string record[6]={"reset","reset board","board add","board delete","reboot backplane","backplane abort"};
string output[6]={"reset what","board fault","where to add","no board at all","impossible","install first"};
//记录空格位置
int recordBlank[6]={0,6,6,6,7,10};
int main()
{
//1.处理输入
string str;
while(getline(cin,str))
{
//没有空格的第一条指令特殊对待
int flag=0;
for(int i=0;i<str.length();i++)
if(str[i]==' ')
{
flag++;
break;
}
//2.没有空格的特殊处理
if(!flag)
{
//避免出现长度超过指令的情况
if(str.length()>record[0].length()) cout<<"unknown command"<<endl;
else
{//处理长度合理,判断是否匹配,输出相应指令
int flag0=1;
for(int i=0;i<str.length();i++)
{
if(str[i]!=record[0][i])
{
flag0=0;
cout<<"unknown command"<<endl;
break;
}
}
if(flag0) cout<<"reset what"<<endl;
}
}//3.如果有空格
else if(flag==1)
{
string str1="";
string str2="";
int flag1=1;
for(int i=0;i<str.length();i++)
{//将指令拆分成两部分进行处理
if(flag1&&str[i]!=' ') str1+=str[i];
else if(str[i]==' ') flag1=0;
else if(!flag1&&str[i]!=' ') str2+=str[i];
}
//判断是否匹配的数组
vector<int> recordCompare;
int i=1;
for(;i<6;i++)
{
//for(int kk=recordBlank[i];kk<record[i].length();kk++) cout<<record[i][kk];cout<<"11"<<endl;
int flag0=1;//前一个子串如果比匹配的长会自动匹配错误,所以不用判断长度
for(int j=0;j<str1.length();j++)
{
if(record[i][j]!=str1[j])
{
flag0=0;
break;
}
}//第一条子串匹配成功,判断第二条子串,注意要匹配长度
if(flag0&&str2.length()<=record[i].length()-recordBlank[i])
{
//cout<<"in "<<record[i]<<endl;
int flag1=1;
for(int j=0;j<str2.length();j++)
{//循环判断
if(record[i][j+recordBlank[i]]!=str2[j])
{
flag1=0;
break;
}
}//推入匹配的字符串编号
if(flag1) recordCompare.push_back(i);
}
}//如果只有一个匹配输出,如果为0或者多个匹配失败
if(recordCompare.size()==1) cout<<output[recordCompare[0]]<<endl;
else cout<<"unknown command"<<endl;
}
}
}
HJ72 百钱买百鸡问题 简单 45.02%
#include<bits/stdc++.h>
using namespace std;
//x+y+z==100
//5*x+3*y+z/3==100
//化简得到x小于等于14 y小于等于25 满足 7*x+4*y==100即可
int main()
{
int n;
if(cin>>n)
{
for(int x=0;x<=14;x++)
for(int y=0;y<=25;y++)
if(7*x+4*y==100)
{
int z=100-x-y;
cout<<x<<' '<<y<<' '<<z<<endl;
}
}
return 0;
}
HJ73 计算日期到天数转换 字符串 简单 40.22%
#include <bits/stdc++.h>
using namespace std;
int main()
{
int year;
int month;
int date;
map<int,int> days;
days[1]=31;days[2]=28;days[3]=31;days[4]=30;
days[5]=31;days[6]=30;days[7]=31;days[8]=31;
days[9]=30;days[10]=31;days[11]=30;days[12]=31;
while(cin>>year>>month>>date)
{
if(year%4==0&&year%100!=0||year%400==0) days[2]++;
int count=0;
for(int i=1;i<month;i++) count+=days[i];
count+=date;
cout<<count<<endl;
}
}
⭐HJ74 参数解析 字符串 简单 35.64%
题解:
- 没有想到将计数和输出分开计算
- 没有想到用“”两个符号夹着输出,只想到考虑空格
#include <bits/stdc++.h>
using namespace std;
int main()
{
string input;
while(getline(cin,input))
{
//统计个数
int length = input.length();
int num = 0;
for(int i=0; i<length; i++)
{
if(input[i] == '"')
{
i++;
while(input[i]!='"') i++;
}
else if(input[i] == ' ')
num++;
}
cout<<num+1<<endl;
//输出
for(int i=0; i<length; i++)
{
if(input[i] == '"')
{
i++;
while(input[i]!='"')
{
cout<<input[i];
i++;
}
}
else if(input[i] ==' ')
cout<<endl;
else
cout<<input[i];
}
cout<<endl;
}
return 0;
}
HJ75 ⭐公共字串计算 字符串 简单 39.13%
#include <bits/stdc++.h>
using namespace std;
int main()
{
std::string a;
std::string b;
getline(std::cin, a);
getline(std::cin, b);
int max_len = 0;
std::string sub_str = "";
for(int i=0; i<a.length(); i++)
{
for(int j=0; j<b.length(); j++)
{
if(a[i] == b[j])
{
for(int m=i, n=j; m<a.length(), n<b.length(); m++, n++)
{
if(a[m] != b[n])
{
break;
}
if((m - i + 1) > max_len)
{
max_len = m - i + 1;
sub_str = a.substr(i, m+1);
}
}
}
}
}
std::cout << max_len << std::endl;
//std::cout << sub_str << std::endl;
}
HJ76 尼科彻斯定理 数学 简单 42.94%
HJ83 二维数组操作 数组 简单 27.33%
题解:根据题意解题
#include<bits/stdc++.h>
using namespace std;
int main()
{
int row,col;
while(cin>>row>>col)
{
//1.输入行列
if(row<=9&&col<=9) cout<<"0"<<endl;
else cout<<"-1"<<endl;
//2.输入交换的坐标
int x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
if(x1+1<=row&&x2+1<=row&&y1+1<=col&&y2+1<=col) cout<<"0"<<endl;
else cout<<"-1"<<endl;
//3.插入x
int insertX;cin>>insertX;
if(row<9&&insertX<row) cout<<"0"<<endl;
else cout<<"-1"<<endl;
//4.c插入y
int insertY;cin>>insertY;
if(col<9&&insertY<col) cout<<"0"<<endl;
else cout<<"-1"<<endl;
//5.查询
int x,y;cin>>x>>y;
if(x<row&&y<col) cout<<"0"<<endl;
else cout<<"-1"<<endl;
}
}
HJ84 统计大写字母个数 字符串 简单 39.97%
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
while(getline(cin,str))
{
int count=0;
for(int i=0;i<str.length();i++)
if(str[i]>='A'&&str[i]<='Z')
count++;
cout<<count<<endl;
}
return 0;
}
HJ85 最长回文子串 字符串穷举 简单 37.98%
题解:中心拓展法,考虑奇数回文和偶数回文
其他方法参考
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
while(cin>>str)
{
int max=0;
int startIndex=0;
//假设是abba偶数形式
for(int i=0;i<str.length();i++)
{
int m=i,n=i+1;
while(m>=0&&n<str.length()&&str[m]==str[n])
{
if(n-m+1>max)
{
max=n-m+1;
startIndex=m;
}
m--;
n++;
}
}
//假设是aba奇数形式
for(int i=0;i<str.length();i++)
{
int m=i-1,n=i+1;
while(m>=0&&n<str.length()&&str[m]==str[n])
{
if(n-m+1>max)
{
max=n-m+1;
startIndex=m;
}
m--;
n++;
}
}
cout<<max<<endl;
}
}
HJ86 求最大连续bit数 位运算 简单 40.91%
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
vector<int>record;
while(n)
{
record.push_back(n%2);
n=n/2;
}
reverse(record.begin(),record.end());
vector<int>index;
for(int i=0;i<record.size();i++)
if(record[i]==0) index.push_back(i);
index.push_back(record.size());
int max=index[0];
for(int i=1;i<index.size();i++)
if(index[i]-index[i-1]>max) max=index[i]-index[i-1]-1;
cout<<max<<endl;
//cout<<max<<endl;
}
return 0;
}
HJ87 密码强度等级 字符串 简单 30.95%
#include<bits/stdc++.h>
using namespace std;
int main(){
string s;
while(getline(cin,s))
{
int score=0;
int num=0;
int schar=0;
int bchar=0;
int flag=0;
//1.长度
if(s.size()<=4)score+=5;
else if(s.size()>=5&&s.size()<=7)score+=10;
else score+=25;
//字母,符号,数字遍历
for(int i=0;i<s.size();i++)
{
if(s[i]>='0'&&s[i]<='9'){
num+=1;
}else if(s[i]>='a'&&s[i]<='z')
{
schar++;
}else if(s[i]>='A'&&s[i]<='Z')
{
bchar++;
}else flag++;
}
//字母得分
if(schar==0&&bchar==0){}
else if((schar!=0&&bchar==0)||(schar==0&&bchar!=0))
{
//单一字母
score+=10;
}else score+=20;
//数字得分
if(num>1)score+=20;
else if(num==1)score+=10;
//符号得分
if(flag>1)score+=25;
else if(flag==1)score+=10;
//奖励
if(schar&&bchar&&flag&&num)score+=5;
else if((schar||bchar)&&flag&&num)score+=3;
else if((schar||bchar)&&num)score+=2;
//得分
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 cout<<"VERY_WEAK"<<endl;
}
}
▲HJ91 走方格的方案数 字符串 简单 43.14%
题解:根据题意写即可,莫名奇妙对了
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m;
while(cin>>n>>m)
{
vector<vector<int>> dp(n+1,vector<int>(m+1,1));
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
dp[i+1][j+1]=dp[i+1][j]+dp[i][j+1];//🔺
}
}
cout<<dp[n][m]<<endl;
}
}
HJ97 记负均正 数组 简单 19.34%
题解:根据题意
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
vector<int> record1;
int count=0;
float ans=0;
while(n--)
{
int temp;cin>>temp;
if(temp>0) record1.push_back(temp);
else if(temp<0) count++;
}
for(int i=0;i<record1.size();i++) ans+=record1[i];
ans=ans/record1.size();
cout<<count<<" ";
printf("%.1f\n",ans);
}
}
HJ100 等差数列 数学 简单 38.17%
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
int sum=n*(n-1)*3/2+2*n;
cout<<sum<<endl;
}
return 0;
}
HJ106 字符逆序 字符串 简单 42.93%
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
getline(cin,str);
reverse(str.begin(),str.end());
cout<<str<<endl;
return 0;
}
HJ108 求最小公倍数 递归 数学
题解:
- 分成两种情况:
- ab可以整除,最大数为最小公约数
- ab不可以整除,最小公倍数为较大数的整数倍,a*b是a和b的公倍数,但不一定是最小的。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a,b;cin>>a>>b;
if(max(a,b)%min(a,b)==0) //两数能整除,较大数为最小公倍数
{
cout<<max(a,b);
}
else
{
for(int i=1; i<= min(a,b);i++)
{
//最小公倍数为较大数的整数倍,a*b是a和b的公倍数,但不一定是最小的。
int num = i*max(a,b);
if(num%a==0 && num%b==0)
{
cout<<num;
break; //第一次找到公倍数就跳出循环
}
}
}
return 0;
}
—————————————————————————————————————————————————————
—————————————————————————————————————————————————————
—————————————————————————————————————————————————————
—————————————————————————————————————————————————————
—————————————————————————————————————————————————————
—————————————————————————————————————————————————————
中等题
HJ5 进制转换 字符串 中等 30.33%
#include<bits/stdc++.h>
#include<string>
using namespace std;
int count(string str)
{
int sum=0;
for(int i=0;i<str.length();i++)
{
if(str[i]=='A') sum+=10*pow(16,i);
else if(str[i]=='B') sum+=11*pow(16,i);
else if(str[i]=='C') sum+=12*pow(16,i);
else if(str[i]=='D') sum+=13*pow(16,i);
else if(str[i]=='E') sum+=14*pow(16,i);
else if(str[i]=='F') sum+=15*pow(16,i);
else sum+=(str[i]-'0')*pow(16,i);
}
return sum;
}
int main()
{
string str;
while(getline(cin,str))
{
str=str.substr(2,str.length());
reverse(str.begin(),str.end());
int sum=count(str);
cout<<sum<<endl;
}
}
⭐HJ6 质数因子 排序 中等 25.93%
#include<bits/stdc++.h>
using namespace std;
int main()
{
long num;
while (cin>>num)
{
int maxi = sqrt(num);
for (int i = 2; i <= maxi; i++) {
while (!(num % i)) { //素数由质数组成,不断除较小的质数,大的素数不会出现
num /= i;
cout<<i<<' ';//找到质数不断除,直到没有这个质数因子
}
}
if (num != 1)
cout<<num<<' '<<endl;//num本身是质数
cout<<endl;
}
return 0;
}
HJ8 合并表记录 中等 32.99%
题解:
- 利用map+set自动去重排序
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
map<int,int>map;
int index,value;
set<int> record;
while(cin>>index>>value)
{
map[index]+=value;
record.insert(index);
}
for(set<int>::iterator it=record.begin();it!=record.end();it++)
cout<<*it<<' '<<map[*it]<<endl;
}
}
HJ9 提取不重复的整数 数组哈希位运算 中等 40.27%
#include <bits/stdc++.h>
using namespace std;
int main()
{
string str;
cin>>str;
map<int,int>map;
for(int i=0;i<str.length();i++)
map[str[i]]++;
for(int i=str.length();i>=0;i--)
if(map[str[i]])
{
cout<<str[i];
map[str[i]]=0;
}
cout<<endl;
}
HJ10 字符个数统计 字符串哈希 中等 43.31%
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
while(cin>>str)
{
map<char,int>map;
for(int i=0;i<str.length();i++)
map[str[i]]=1;
int count=0;
for(char i=0;i<127;i++)
if(map[char(i)]) count++;
cout<<count<<endl;
}
}
HJ14 字符串排序 字符串 中等 38.08%
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
vector<string> record;
string str;
for(int i=0;i<n;i++)
{
cin>>str;
record.push_back(str);
}
sort(record.begin(),record.end());
for(int i=0;i<record.size();i++)
cout<<record[i]<<endl;
}
return 0;
}
HJ16 购物单 动态规划 中等 19.61%
#include<bits/stdc++.h>
using namespace std;
//题目中的除10是一个优化的手段,这是一个背包问题的提升
int main(){
//--------------------------------------------------
//处理输入的总钱数 和 总件数
int M,N;
cin>>M>>N;
M/=10;//除10是为了优化
//--------------------------------------------------
//形成价格表price和价值表value,都是二维数组
vector<vector<int>> price(N+1,vector<int>(3,0));
vector<vector<int>> value(N+1,vector<int>(3,0));
//之所以列为三,是因为包含主件,附件1,附件2三种存在的可能性
//先将主件的价格,价值存入二维数组
for(int i=1;i<=N;i++){
int a,b,c;
cin>>a>>b>>c;
if(c==0){
price[i][0]=a/10;
value[i][0]=b;
}
else{//当存入了附件一后再存入附件二
if(price[c][1]!=0){
price[c][2]=a/10;
value[c][2]=b;
}
else{//优先存入附件一的价格和价值
price[c][1]=a/10;
value[c][1]=b;
}
}
}
//--------------------------------------------------
//接下来就是考虑,主件,附件是否加入到背包中的情况
//简单的转移方程为 dp[i][j]=j>=a?max(dp[i-1][j-a]+a*b,dp[i-1][j]):dp[i-1][j];
//dp[i-1][j-a]+a*b,放入背包;dp[i-1][j],不放入背包;
vector<vector<int>> dp(N+1,vector<int>(M+1,0));
for(int i=1;i<=N;i++){//N是件数,M是总价格
for(int j=1;j<=M;j++){
int a=price[i][0],b=value[i][0];
int c=price[i][1],d=value[i][1];
int e=price[i][2],f=value[i][2];
dp[i][j]=j>=a?max(dp[i-1][j-a]+a*b,dp[i-1][j]):dp[i-1][j];
dp[i][j]=j>=a+c?max(dp[i-1][j-a-c]+a*b+c*d,dp[i][j]):dp[i][j];
dp[i][j]=j>=a+e?max(dp[i-1][j-a-e]+a*b+e*f,dp[i][j]):dp[i][j];
dp[i][j]=j>=a+c+e?max(dp[i-1][j-a-e-c]+a*b+c*d+e*f,dp[i][j]):dp[i][j];
}
}
cout<<dp[N][M]*10<<endl;
return 0;
}
//背包问题如下
//在背包问题中,设dp[i][j]表示在钱数不超过j的条件下,对于前i件产品的选择所能获取的最大价值。
//动态方程可以表示为
//如果j>price[i] dp[i][j]=max(dp[i-1][j-price[i]]+value[i],dp[i-1][j])
//否则 dp[i][j]=dp[i-1][j])
HJ21 简单密码破解 字符串 中等 38.27%
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
while(cin>>str)
{
string temp="";
for(int i=0;i<str.length();i++)
{
if(str[i]<='Y'&&str[i]>='A') temp+=str[i]-'A'+'b';
else if(str[i]=='Z') temp+='a';
else if(str[i]<='9'&&str[i]>='0') temp+=str[i];
else if(str[i]=='a'||str[i]=='b'||str[i]=='c') temp+='2';
else if(str[i]=='d'||str[i]=='e'||str[i]=='f') temp+='3';
else if(str[i]=='g'||str[i]=='h'||str[i]=='i') temp+='4';
else if(str[i]=='j'||str[i]=='k'||str[i]=='l') temp+='5';
else if(str[i]=='m'||str[i]=='n'||str[i]=='o') temp+='6';
else if(str[i]=='p'||str[i]=='q'||str[i]=='r'||str[i]=='s') temp+='7';
else if(str[i]=='t'||str[i]=='u'||str[i]=='v') temp+='8';
else if(str[i]=='w'||str[i]=='x'||str[i]=='y'||str[i]=='z') temp+='9';
}
cout<<temp<<endl;
}
}
HJ26 字符串排序 排序字符串 中等 33.56%
#include<bits/stdc++.h>
using namespace std;
int main()
{
//处理输入
string str;
while(cin>>str)
{
//判断输入是否包含大小写字母
int flagMin=0,flagMax=0;
string str1="";
vector<char> record(str.length());
vector<int> blankplace;//控制非字母位置
for(int i=0;i<str.length();i++) blankplace.push_back(i);
for(int i=0;i<str.length();i++)
{//将其他字符先存入
if(str[i]<='z'&&str[i]>='a')
{
flagMin=1;
str1+=str[i];
}
else if(str[i]<='Z'&&str[i]>='A')
{
flagMax=1;
str1+=str[i];
}
else
{//存入,并控制输入位置
record[i]=str[i];
blankplace[i]=-1;
}
}
//如果只有大写或者只有小写
if(flagMin==0&&flagMax==1||flagMin==1&&flagMax==0)
{
sort(str1.begin(),str1.end());
int index=0;
for(int i=0;i<record.size();i++)
if(!record[i]) record[i]=str1[index++];
}
else
{//大小写字母都有
char compare1='a';
char compare2='A';
int index=0;
//cout<<str1<<endl;
while(compare1<='z')
{
for(int i=0;i<str1.length();i++)
{//主动控制a-z的顺序
if(str1[i]==compare1||str1[i]==compare2)
{
while(blankplace[index]==-1) index++;
record[index]=str1[i];
blankplace[index]=-1;
}
}
compare1=((compare1-'a')+1)+'a';
compare2=((compare2-'A')+1)+'A';
}
}
for(int i=0;i<record.size();i++)
cout<<record[i];
cout<<endl;
}
}
HJ34 图片整理 字符串 中等 42.77%
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
while(cin>>str)
{
sort(str.begin(),str.end());
cout<<str<<endl;
}
}
HJ35 蛇形矩阵 数组 中等 39.60%
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
vector<vector<int>> record(n,vector<int>(n));
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
record[i][j]!=0;
}
}
int flag=1;
for(int i=0;i<n;i++)
{
int begin=0;
for(int j=0;j<=i;j++)
{
// cout<<"1"<<endl;
record[i-begin][begin]=flag++;
// cout<<record[i-begin][begin];
begin++;
}
// cout<<endl;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
// int temp=record[i][j];
// record[i][j]=record[j][i];
// record[j][i]=temp;
if(record[i][j]) cout<<record[i][j]<<" ";
}
cout<<endl;
}
}
}
//0 0
//0 1 1 0
//0 2 1 1 2 0
HJ36 字符串加密 字符串 中等 37.67%
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
string compare;
//获取输入
while(cin>>str>>compare)
{
string str1="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
//加密对照去重
//str.erase(unique(str.begin(),str.end()),str.end());
string temp="";
for(int i=0;i<str.length();i++)
{
int flag=1;
for(int j=0;j<temp.length();j++)
{
if(str[i]==temp[j]) flag=0;
}
if(flag) temp+=str[i];
}
str=temp;
//cout<<str<<endl<<endl;
//形成密文对照
for(int i=0;i<str.length();i++) str[i]=toupper(str[i]);
string ans=str;
for(int i=0;i<str1.length();i++)
{
int flag=0;
for(int j=0;j<str.length();j++)
{
if(str1[i]==str[j]) flag=1;
}
if(!flag) ans+=str1[i];
}
//cout<<compare<<endl;
//cout<<ans<<endl;
//cout<<str1<<endl;
//输出加密后的字符串
for(int i=0;i<compare.length();i++)
{
for(int j=0;j<ans.length();j++)
{
if(compare[i]==str1[j]) cout<<ans[j];
else if(compare[i]-'a'+'A'==str1[j])
{
char temp=ans[j]-'A'+'a';
cout<<temp;
}
}
}
cout<<endl;
//cout<<endl;
}
}
HJ38 求小球落地5次后所经历的路程和第5次反弹的高度 模拟 中等 35.11%
#include<bits/stdc++.h>
using namespace std;
int main()
{
float n;
while(cin>>n)
{
float sum;
for(int i=0;i<4;i++)
{
sum+=n+n/2;
n=n/2;
}
sum+=n;
n/=2;
printf("%.6f\n",sum);
printf("%.6f\n",n);
}
}
HJ40 输入一行字符,分别统计出包含英文字母、空格、数字和其它字符的个数 字符串 中等 40.13%
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
while(getline(cin,str))
{
int num=0;
int a=0;
int blank=0;
int other=0;
for(int i=0;i<str.length();i++)
{
if(str[i]<='9'&&str[i]>='0') num++;
else if(str[i]==' ') blank++;
else if(str[i]<='z'&&str[i]>='a') a++;
else other++;
}
cout<<a<<endl<<blank<<endl<<num<<endl<<other<<endl;
}
}
⭐⭐⭐HJ43 迷宫问题 排序 中等 33.63%
我写的错了,不想改了
#include<bits/stdc++.h>
using namespace std;
bool way(int i,int j,vector<vector<int>>record,int n,int m,vector<int>ways)
{
if(i>=0&&i<n&&j>=0&&j<m&&record[i][j]==0)
{
cout<<"int"<<endl;
record[i][j]=1;
ways.push_back(i);
ways.push_back(j);
if(i==n-1&&j==m-1)
{
return true;
}
way(i+1,j,record,n,m,ways);
way(i,j+1,record,n,m,ways);
way(i-1,j,record,n,m,ways);
way(i,j-1,record,n,m,ways);
record[i][j]=0;
// ways.pop_back();
//ways.pop_back();
}
else return false;
}
int main()
{
int n,m;
while(cin>>n>>m)
{
int temp=n*m;
vector<vector<int>> record(n,vector<int>(m));
vector<int> ways;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
cin>>record[i][j];
bool judge=way(0,0,record,n,m,ways);
cout<<ways.size()<<endl;
for(int i=0;i<ways.size();i++) cout<<ways[i];
}
}
AC代码
#include<iostream>
#include<vector>
using namespace std;
int n,m;
vector<vector<int>> maze;
//当从(0,0)到(n-1,m-1)有多条通路时,best_path记录最小的temp_path
//本题只有一条通路,所以当到达(n-1,m-1)时,让 best_path=temp_path即可
vector<vector<int>> best_path;
vector<vector<int>> temp_path;
void dfs(int i,int j)
{
//边界条件:(1)数组越界(2)“墙壁”或已走过
if(i<0||i>=n||j<0||j>=m||maze[i][j]==1)
{
return;
}
maze[i][j]=1;//该位置已走过标记为1🔺
temp_path.push_back({i,j});//将该位置加入路径
if(i==n-1&&j==m-1)//走到终点
{
//多条路径时best_path记录最小的temp_path
//if(temp_path.size()<best_path.size()||best_path.empty())
//{
// best_path=temp_path;
//}
//本题只有一条通路,所以当到达(n-1,m-1)时,让 best_path=temp_path即可
best_path=temp_path;
}
dfs(i-1,j);//上
dfs(i+1,j);//下
dfs(i,j-1);//左
dfs(i,j+1);//右
maze[i][j]=0;//该结点走不通时,恢复原场面🔺
temp_path.pop_back();//从路径中删除该节点
}
int main()
{
while(cin>>n>>m)//一次测试中多个案例依次输入
{
maze=vector<vector<int>>(n,vector<int>(m,0));//设置地图的大小并初始化
//一次测试中多个案例依次输入时,每个案例执行完后将路径容器清空
best_path.clear();
temp_path.clear();
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cin>>maze[i][j];
}
}
dfs(0,0);
for(vector<vector<int>>::iterator
it=best_path.begin();it!=best_path.end();it++)
{
cout<<'('<<(*it)[0]<<','<<(*it)[1]<<')'<<endl;
}
}
return 0;
}
HJ45 名字的漂亮度 字符串 中等 34.29%
#include<bits/stdc++.h>
using namespace std;
//主要是理解可能的最大漂亮度,自己设定出现次数最多的字母漂亮度最大就可以了
int main()
{
int n;
while(cin>>n)
{
while(n--)
{
map<char,int>map;
for(int i=0;i<26;i++)
map[i+'a']=0;
string str;
cin>>str;
for(int i=0;i<str.length();i++)
map[str[i]]++;
vector<int> record;
for(int i=0;i<26;i++)
if(map[i+'a'])
record.push_back(map[i+'a']);
sort(record.begin(),record.end());
reverse(record.begin(),record.end());
int index=26;
int sum=0;
for(int i=0;i<record.size();i++)
{
sum+=index*record[i];
index--;
}
cout<<sum<<endl;
}
}
}
HJ46 按字节截取字符串 字符串 中等 41.95%
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
int n;
while(cin>>str>>n)
{
for(int i=0;i<n&&i<str.length();i++)
{
cout<<str[i];
}
cout<<endl;
}
}
⭐⭐HJ48 从单向链表中删除指定值的节点 链表 中等 34.81%
题解:AC了,但是感觉不是很清晰,加了太多额外判断的条件了
#include <bits/stdc++.h>
using namespace std;
//使用动态规划来处理这道题
int main()
{
string str1;
string str2;
while(cin>>str1>>str2)
{
vector<vector<bool>> dp(str1.length()+1,vector<bool>(str2.length()+1));
for(int i=0;i<=str1.length();i++)
{
for(int j=0;j<=str2.length();j++)
{
dp[i][j]=false;
}
}//初始化整个dp数组
dp[0][0]=true;//空字符对空字符必然是true
if(str1[0]=='*') //如果开头是*,那么可以匹配所有的空字符,自己想象一个dp数组即可,
for(int i=0;i<str1.length();i++)
dp[i][0]=true;
for(int i=0;i<str1.length();i++)
{
for(int j=0;j<str2.length();j++)
{//进入dp数组,dp数组只能从之前就连续的位置继续判断是否连续,如果说之前是*,可以跳位判断
if(dp[i][j]||i-1>=0&&str1[i-1]=='*'&&dp[i-1][j])
{//如果字符符合要求,进入下一步判断
if(str2[j]<='9'&&str2[j]>='0'||str2[j]>='a'&&str2[j]<='z'||str2[j]>='A'&&str2[j]<='Z'||str2[j]=='.')
{//判断字符是否相等,考虑大小写问题
if(str2[j]==str1[i]||str2[j]-'A'+'a'==str1[i]||str2[j]-'a'+'A'==str1[i]) dp[i+1][j+1]=true;
else if(str2[j]!=str1[i])
{//如果不相等,考虑通配符
if(str1[i]=='?') dp[i+1][j+1]=true;//是?,可以直接跳到右对角线的下一步
else if(str1[i]=='*')
{//如果是*,整行都可以匹配
for(int k=j;k<str2.length();k++) dp[i+1][k+1]=true;
}
else dp[i+1][j+1]=false;//如果都不符合就是不连续
}
}
}
}
}
// for(int i=0;i<=str1.length();i++)
// {
// for(int j=0;j<=str2.length();j++)
// cout<<dp[i][j];
// cout<<endl;
// }
if(dp[str1.length()][str2.length()]==true) cout<<"true"<<endl;
else cout<<"false"<<endl;//最后一位是正确的就可以了
}
}
⭐⭐⭐HJ52 计算字符串的距离 字符串 中等 37.26%
题解:
- 利用动态规划,比较word1前i个字符和word2前j个字符,形成dp表,每次取最小值
参考链接
#include<bits/stdc++.h>
using namespace std;
int main()
{
string word1;
string word2;
while(cin>>word1>>word2)
{
int n = word1.size(), m = word2.size();
vector <vector<int>> dp(n + 1, vector<int>(m + 1));
for(int i = 1; i <= n; i++) dp[i][0] = i;//word1距离空字符串的距离
for(int i = 1; i <= m; i++) dp[0][i] = i;//word2距离空字符串的距离
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
//如果说两者的字符相等,则不需要修改,直接继承word1和word2前一个字符的数值
if(word1[i - 1] == word2[j - 1]) dp[i][j] = dp[i - 1][j - 1];
else {//如果两个字符不相等,存在两种修改
//一是两者同时修改,二是word1删掉一个(=word2增加一个),三是word1增加一个(=word2删除一个)
dp[i][j] = min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i][j - 1])) + 1;
}
}
}
cout<<dp[n][m]<<endl;
}
}
HJ55 挑7 穷举数学 中等 40.47%
题解:
- 抓住两个条件 含’7’或者7的倍数
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
vector<int>compare;
for(int i=1;i<=n;i++)
{
if(i%7==0) compare.push_back(i);//cout<<i<<endl;}
else
{
string str=to_string(i);
for(int i=0;i<str.length();i++)
if(str[i]=='7')
{
compare.push_back(i);
break;
}
}
}
int count=0;
for(int j=0;j<compare.size();j++)
if(compare[j]<=n) count++;
cout<<count<<endl;
}
}
HJ57 高精度整数加法 字符串 中等 35.87%
#include<bits/stdc++.h>
using namespace std;
int main()
{
//1.读入两个字符串
string str1;
string str2;
while(cin>>str1>>str2)
{
//2.因为要做加法,将字符串反向
string res1=str1;
string res2=str2;
reverse(res1.begin(),res1.end());
reverse(res2.begin(),res2.end());
int flag=0;
//3.让第一个字符串永远是最小的
if(res1.length()>res2.length()) swap(res1,res2);
string res="";
//4.处理相同长度的加法
for(int i=0;i<res1.length();i++)
{
if(res1[i]-'0'+res2[i]-'0'+flag<=9)
{
res+=(res1[i]-'0'+res2[i]-'0'+flag)+'0';
flag=0;
}
else if(res1[i]-'0'+res2[i]-'0'+flag>9)
{
res+=(res1[i]-'0'+res2[i]-'0'+flag)%10+'0';
flag=(res1[i]-'0'+res2[i]-'0'+flag)/10;
}
}
//5.如果长度相等,处理有可能多出来的一位
if(res1.length()==res2.length()&&flag)
if(flag) res+=flag+'0';
//6.如果只多一位
if(res1.length()+1==res2.length()&&flag)
{
if(res2[res1.length()]-'0'+flag<=9) res+=(res2[res1.length()]-'0'+flag)+'0';
else
{
res+=(res2[res1.length()]-'0'+flag)%10+'0';
flag=(res2[res1.length()]-'0'+flag)/10;
res+=flag+'0';
}
}
int length;
//7.如果多了不止一位,但是不存在进位
if(res1.length()+1<res2.length()&&!flag) for(int i=res1.length();i<res2.length();i++) res+=res2[i];
//8.多了不止一位,存在进位
if(res1.length()+1<res2.length()&&flag)
{
//cout<<"in"<<endl;
//8.1如果进位就一次,简单处理
if(res2[res1.length()]-'0'+flag<=9)
{
res+=(res2[res1.length()]-'0'+flag)+'0';
flag=0;
//cout<<"in"<<endl;
for(int i=res1.length()+1;i<res2.length();i++) res+=res2[i];
}
//8.2如果进位存在多次
else
{
//8.2.1先处理肯定多出来的哪一位
length=res1.length();
res+=(res2[length]-'0'+flag)%10+'0';
flag=(res2[length]-'0'+flag)/10;
length++;
//8.2.2继续判断是否还需要持续进位,直到进位结束
while(flag!=0&&length<res2.length())
{
//cout<<"in"<<endl;
if(res2[res1.length()]-'0'+flag<=9)
{
res+=(res2[length++]-'0'+flag)+'0';
flag=0;
}
else
{
res+=(res2[length]-'0'+flag)%10+'0';
flag=(res2[length]-'0'+flag)/10;
length++;
}
}
//cout<<length<<endl;
//cout<<flag<<endl;
//8.3如果这个进位超过了较长串的位数
if(flag!=0)
{
cout<<"in"<<endl;
res+=flag+'0';
length++;
for(int i=length;i<res2.length();i++) res+=res2[i];
}
//8.4如果任然存在,继续加入
for(int i=length;i<res2.length();i++) res+=res2[i];
}
}
//for(int i=length;i<res2.length();i++) res+=res2[i];
//cout<<length<<endl;
//for(int i=res1.length();i<res2.length();i++) res+=res2[i];
//9.翻转串,输出
reverse(res.begin(),res.end());
for(int i=0;i<res.length();i++) cout<<res[i];cout<<endl;
}
}
HJ59 找出字符串中第一个只出现一次的字符 字符串 中等 30.02%
题解:照题意使用map即可
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
while(cin>>str)
{
map<char,int>map;
int startIndex=0;
for(int i=0;i<str.length();i++)
map[str[i]]++;
for(int i=0;i<str.length();i++)
if(map[str[i]]==1)
{
startIndex=i;
break;
}
if(map[str[startIndex]]==1)cout<<str[startIndex]<<endl;
else if(map[startIndex]!=1) cout<<"-1"<<endl;
}
}
HJ60 查找组成一个偶数最接近的两个素数 穷举数学 中等 41.17%
#include <iostream>
using namespace std;
bool isPrime(int n)
{//判断是否是素数
int i=0;
for(i=2;i*i<=n;i++)
{
if(n%i==0) return false;
}//因子只有自己
return true;
}
int main()
{
int n;
while(cin>>n)
{
int left=n/2;
int right=n/2;
while(left>=2)
{//如果两个都是素数,输出
if(isPrime(left)&&isPrime(right))
{
cout<<left<<endl;
cout<<right<<endl;
break;
}
else
{
left--;
right++;
}
}
}
return 0;
}
HJ63 DNA序列 字符串 中等 39.37%
题解:
- 处理特定长度的字符串即可,计算其中的CG数目就可以,找到数目最多且开始最早的位置就可以了。最早的位置简单通过要大于max就可以控制了
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
int n;
int beginIndex=0;
int max=0;
while(cin>>str>>n)
{
int ratio=0;
for(int i=0;i<str.length()-n;i++)
{
int temp=0;
for(int j=i;j<i+n;j++)
if(str[j]=='C'||str[j]=='G') temp++;
//cout<<temp<<endl;
if(temp>max)
{
beginIndex=i;
max=temp;
}
}
for(int i=beginIndex;i<beginIndex+n;i++)
cout<<str[i];
cout<<endl;
}
}
HJ64 MP3光标位置 数组 中等 29.67%
题解:见注释
//分析题意
//1.如果n是小于4的话,只需要判断歌曲数就可以做出来了,当遇到是第一首歌还要往上的时候,转到最后一首歌
//如果是最后一首歌还要往下,转到第一首歌,其他的正常变化
//2.如果n是大于是的话,需要一个光标pos和一个判断歌曲数的index
//当光标是第一个时,如果还要往上,光标还是第一个
//当光标是最后一个时,如果还要往下,光标还是最后一个
//歌曲数目和之前变化是一样的
//其他翻页很简单
#include<iostream>
using namespace std;
#include<string>
int main()
{
int num;
string str;
while(cin>>num>>str)
{
int index=1;
int len=str.length();
int Up=0,Down=0;
int pos=0; //记录当前光标的位置
if(num<=4)
{
for(int i=0;i<len;++i)
{
if(index==num&&str[i]=='D')index=1;
else if(index==1&&str[i]=='U')
index=index-1+num;
else if(str[i]=='U')index--;
else if(str[i]=='D')index++;
}
for(int i=1;i<=num;++i)
cout<<i<<" ";
}
else
{
for(int i=0;i<len;++i)
{
if(index==num&&str[i]=='D'){
index=1;
pos=1;
}
else if(index==1&&str[i]=='U'){
index=num;
pos=4;
}
else if(str[i]=='U'){
index--;//记录第几首歌,后面打印的东西
if(pos!=1) pos--;
else pos=1;//如果光标本来就在第一个了,向上翻还是第一个
}
else if(str[i]=='D'){
index++;
if(pos!=4) pos++;
else pos=4;
}
}
switch(pos)//pos决定了页面打印范围
{
case 1:
{
for(int i=index;i<index+4;++i)
cout<<i<<" ";
break;
}
case 2:
{
for(int i=index-1;i<index+3;++i)
cout<<i<<" ";
break;
}
case 3:
{
for(int i=index-2;i<index+2;++i)
cout<<i<<" ";
break;
}
case 4:
{
for(int i=index-3;i<index+1;++i)
cout<<i<<" ";
break;
}
}
}
cout<<endl<<index<<endl;
}
return 0;
}
HJ65 查找两个字符串a,b中的最长公共子串 字符串 中等 33.79%
题解:
- 运用动态规划,处理问题,如果相等,在前一个的基础上加一;如果不相等,等于0,意味着没有相同子串,注意不等于1;
- 参考头部给出的几个动态规划的博客理解
- 注意是子串,不是子序列
#include<bits/stdc++.h>
using namespace std;
int main(){
string str1;
string str2;
while(cin>>str1>>str2)
{
if(str1.length()>str2.length()) swap(str1,str2);
vector<vector<int>> res(str1.length()+1,vector<int>(str2.length()+1));
for(int i=0;i<str1.length()+1;i++)
for(int j=0;j<str2.length();j++)
res[i][j]=0;
int max=0;int index=0;
for(int i=0;i<str1.length();i++)
for(int j=0;j<str2.length();j++)
{
if(str1[i]==str2[j]) res[i+1][j+1]=res[i][j]+1;
if(res[i+1][j+1]>max)
{
max=res[i+1][j+1];
index=i;
}
}
string temp="";
while(max--) temp+=str1[index--];
reverse(temp.begin(),temp.end());
cout<<temp<<endl;
}
}
⭐⭐⭐HJ67 24点游戏算法 搜索dfs 中等 34.66%
#include<stdio.h>
#include<string.h>
double num[4],flag=0;
bool vis[4];
void dfs(int step,double sum){
if(step==3){
if(sum==24){
flag=1;
return ;
}
}else{
step++;//vis控制输入的数字
for(int i=0;i<4;i++){
if(vis[i]==0){
vis[i]=1;
dfs(step,sum+num[i]);
dfs(step,sum-num[i]);
dfs(step,sum*num[i]);
dfs(step,sum/num[i]);
vis[i]=0;
}
}
}
}
int main(){
while(scanf("%lf %lf %lf %lf",&num[0],&num[1],&num[2],&num[3])!=EOF){
flag=0;
for(int i=0;i<4;i++)vis[i]=0;
dfs(-1,0);
if(flag==1){
printf("true\n");
}else{
printf("false\n");
}
}
return 0;
}
HJ69 矩阵乘法 数组 中等 40.92%
题解:
- 处理输入输出,然后对着公式进行,注意z赋值时第二个循环是by
#include <bits/stdc++.h>
using namespace std;
int main()
{
int ax;
int ay,bx;
int by;
while(cin>>ax>>ay>>by)
{
bx=ay;
vector<vector<int>> a(ax,vector<int>(ay));
vector<vector<int>> b(bx,vector<int>(by));
for(int i=0;i<ax;i++)
for(int j=0;j<ay;j++)
cin>>a[i][j];
for(int i=0;i<bx;i++)
for(int j=0;j<by;j++)
cin>>b[i][j];
vector<vector<int>> c(ax,vector<int>(by));
for(int i=0;i<ax;i++)
{
for(int j=0;j<by;j++)//注意此处,是用by
{
c[i][j]=0;
for(int z=0;z<ay;z++)
{
c[i][j]+=a[i][z]*b[z][j];
}
cout<<c[i][j]<<' ';
}
cout<<endl;
}
}
}
HJ70 矩阵乘法计算量估算 字符串 中等 38.65%
HJ71 字符串通配符 字符串 中等 30.60%
▲HJ88 扑克牌大小 字符串队列链表栈 中等 32.57%
根据题意写即可
#include<bits/stdc++.h>
using namespace std;
void print(vector<string> res)
{
for(int i=0;i<res.size();i++)
{
cout<<res[i];
if(i!=res.size()-1) cout<<" ";
else cout<<endl;
}
}
int main()
{
//--------------------------------------------------------
//处理输入
string str;
while(getline(cin,str))
{
map<string,int>map=
{
{"1",1},{"2",15},{"3",3},{"4",4},{"5",5},{"6",6},{"7",7},{"8",8},{"9",9},\
{"10",10},{"J",11},{"Q",12},{"K",13},{"A",14}
};
vector<string> str1;
vector<string> str2;
int flagLine=0;
for(int i=0;i<str.length();i++)
if(str[i]=='-')
{
flagLine=i;
break;
}
for(int i=0;i<flagLine;i++)
{
if(str[i]!=' ')
{
int m=i;
string temp="";
while(i<str.length()&&str[i]!=' '&&str[i]!='-')
{
temp+=str[i];
i++;
}
str1.push_back(temp);
}
}
for(int i=flagLine+1;i<str.length();i++)
{
if(str[i]!=' ')
{
int m=i;
string temp="";
while(i<str.length()&&str[i]!=' '&&str[i]!='-')
{
temp+=str[i];
i++;
}
str2.push_back(temp);
}
}
//--------------------------------------------------------
//判断是否有王炸的出现
int flagJoker=0;
for(int i=0;i<str1.size();i++)
{
if(str1[i]=="joker"||str1[i]=="JOKER")
{
cout<<"joker JOKER"<<endl;
flagJoker=1;
break;
}
}
for(int i=0;i<str2.size();i++)
{
if(str2[i]=="joker"||str2[i]=="JOKER")
{
cout<<"joker JOKER"<<endl;
flagJoker=1;
break;
}
}
//--------------------------------------------------------
//没有王炸,正常处理
if(flagJoker==0)
{
//处理其他情况
if(str1.size()==str2.size())
{
if(map[str1[0]]>map[str2[0]]) print(str1);
else print(str2);
}
else if(str1.size()==4&&str2.size()!=4) print(str1);
else if(str2.size()==4&&str1.size()!=4) print(str2);
else cout<<"ERROR"<<endl;
}
}
}
HJ90 合法IP 字符串链表栈队列 中等 35.19%
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long a,b,c,d;
char dot;
while(cin>>a>>dot>>b>>dot>>c>>dot>>d)
{
string res;
if(a<=255&&a>=0&&b<=255&&b>=0&&c<=255&&c>=0&&d<=255&&d>=0) res="YES";
else res="NO";
cout<<res<<endl;
}
}
HJ96 表示数字 字符串 中等 30.72%
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
while(cin>>str)
{
string temp="";
int flag=0;
for(int i=0;i<str.length();i++)
{
if(str[i]<'0'||str[i]>'9')
{
if(!flag)temp+=str[i];
else if(flag)
{
temp+="*";
temp+=str[i];
flag=0;
}
}
else if(str[i]>='0'&&str[i]<='9')
{
if(!flag)
{
temp+="*";
temp+=str[i];
flag=1;
}
else temp+=str[i];
}
}
if(str[str.length()-1]<='9'&&str[str.length()-1]>='0') temp+="*";
cout<<temp<<endl;
}
}
⭐⭐⭐HJ98 自动售货系统 字符串 中等 25.15%
https://www.nowcoder.com/practice/cd82dc8a4727404ca5d32fcb487c50bf?tpId=37&&tqId=21321&rp=1&ru=/ta/huawei&qru=/ta/huawei/question-ranking
⭐HJ99 自守数 中等 35.34%
题解:
- 没有想到只有0 1 5 6才有自守数
/*
求自守数的解题思路
规律:个位数为 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
*/
#include <iostream>
#include <string>
using namespace std;
//求整数 n 以内自守数的接口
int CalcAutomorphicNumbers(int n)
{
int count = 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 pos = s2.size()- s1.size();
if(s2.find(s1,pos) != -1)//从pos找字符串为s1的的下标
{//可以单纯找s1 s2.find(s1)
count++;
}
}
}
return count;
}
int main()
{
int n;
while(cin >> n)
{
cout << CalcAutomorphicNumbers(n) << endl;
}
HJ102 字符统计 字符串排序 中等 28.64%
题解:
- 关键先对字符串排序,这样就是按ascii码排序的,后面只用考虑度的问题了
- 用map处理度
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
while(cin>>str)
{
map<char,int>map;
int max=0;
sort(str.begin(),str.end());
for(int i=0;i<str.length();i++)
{
map[str[i]]++;
if(map[str[i]]>max) max=map[str[i]];
}
while(max)
{
for(int i=0;i<str.length();i++)
if(map[str[i]]==max)
{
cout<<str[i];
map[str[i]]=0;
}
max--;
}
cout<<endl;
}
}
⭐J103 Redraiment的走法 排序 中等 26.53%
#include<bits/stdc++.h>
using namespace std;
//思路:
// 不论从哪开始走,第一步值为1
// dp = [1]
// 针对一根桩子,往前看,第i根桩子的步数必然是前面比它矮的最近一根的步数 + 1
// 状态转移方程:
// 当arr[i] > arr[i - 1]时,必然有dp[i] = dp[i - 1] + 1
int main()
{
int n;
while(cin>>n)
{
vector<int>record;
int dp[n];
for(int i=0;i<n;i++)
{
int temp;
cin>>temp;
record.push_back(temp);
dp[i]=1;
}//5 4 5 1 5 2
for(int i=0;i<n;i++)
{
for(int j=0;j<i;j++)
{
if(record[i]>record[j])dp[i]=max(dp[i],dp[j]+1);
}
}
int max=1;
for(int i=0;i<n;i++)
{
if(dp[i]>max)max=dp[i];
}
cout<<max<<endl;
}
}
⭐⭐⭐HJ107 求解立方根 数学二分 中等 27.30%
#include<bits/stdc++.h>
using namespace std;
int main()
{
double d;
double x=10000.0;
cin>>d;
while(abs(x*x*x-d)>0.000001)
{
x=x-(x*x*x-d)/(3*x*x);
}
printf("%.1lf\n",x);
return 0;
}
求解参考
—————————————————————————————————————————————————————————————
较难题
HJ1 字符串最后一个单词的长度 字符串 较难 29.61%
#include <bits/stdc++.h>
using namespace std;
int main()
{
string str;
while(getline(cin,str))
{
int flag=0;
for(int i=str.length()-1;i>0;i--)
{
if(str[i]==' ')
{
int num=str.length()-i-1;
cout<<num<<endl;
flag=1;
break;
}
}
if(!flag) cout<<str.length()<<endl;
}
return 0;
}
HJ2 计算字符个数 字符串哈希 较难 28.00%
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
char compare;
while(getline(cin,str)&&cin>>compare)
{
int count=0;
for(int i=0;i<str.length();i++)
if(str[i]==compare||str[i]-'a'+'A'==compare||str[i]-'A'+'a'==compare)
count++;
cout<<count<<endl;
}
}
⭐HJ3 明明的随机数 数组 较难 19.88%
题解:
- 使用set自动排序
- insert iterator
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
set<int> record;
while(n--)
{
int num;
cin>>num;
record.insert(num);//--------------------------------------------
//if(find(record.begin(),record.end())==record.end())record.push_back(num);
}
set<int>::iterator it;
for(it=record.begin();it!=record.end();it++)//--------------------------------------------
cout<<*it<<endl;
}
return 0;
}
HJ4 字符串分隔 字符串 较难 26.23%
题解:
- 用一个外部flag指示,一边输入一边输出,通过添加空格符判断是否处理完一条输入
#include <bits/stdc++.h>
using namespace std;
int main()
{
vector<string> record;
string str;
while(cin>>str)
{
str=str+' ';
record.push_back(str);
}
int count=0;
for(int i=0;i<record.size();i++)
{
for(int j=0;j<record[i].length();j++)
{
if(record[i][j]!=' '&&count<8)
{
cout<<record[i][j];
count++;
}
else if(record[i][j]!=' '&&count==8)
{
cout<<endl<<record[i][j];
count=1;
}
else if(record[i][j]==' '&&count<8)
{
for(int i=count;i<8;i++)
cout<<'0';
cout<<endl;
count=0;
}
}
}
}
HJ13 句子逆序 数组 较难 36.49%
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
while(getline(cin,str))
{
reverse(str.begin(),str.end());
for(int i=0;i<str.length();i++)
{
int m=i;
while(i<str.length()&&str[i]!=' ') i++;
reverse(str.begin()+m,str.begin()+i);
}
cout<<str<<endl;
}
}
HJ17 坐标移动 字符串 较难 21.65%
HJ20 密码验证合格程序 数组字符串 较难 26.20%
HJ23 删除字符串中出现次数最少的字符 字符串 较难 29.92%
⭐⭐HJ24 合唱队 队列动态规划 较难 24.42%
题解:
- 使用动态规划,从0-(n-1)考虑递增的,从(n-1)-0考虑递减的
- dp[i]=max(dp[i],dp[j]+1)
参考链接
#include<bits/stdc++.h>
using namespace std;
#define MAX 3000
int main()
{
int n;
while(cin>>n)
{
vector<int>record;
int temp=n;
while(temp--)
{
int temp;
cin>>temp;
record.push_back(temp);
}
int dp1[MAX];
int dp2[MAX];
int sum=0;
for(int i=0;i<record.size();i++)
{
dp1[i]=1;
for(int j=0;j<i;j++)
if(record[j]<record[i]) dp1[i]=max(dp1[j]+1,dp1[i]);
}
for(int i=record.size()-1;i>=0;i--)
{
dp2[i]=1;
for(int j=record.size()-1;j>i;j--)
if(record[j]<record[i]) dp2[i]=max(dp2[j]+1,dp2[i]);
}
for(int i=0;i<record.size();i++)
if(dp1[i]+dp2[i]-1>sum)sum=dp1[i]+dp2[i]-1;
int minSum=n-sum;
cout<<minSum<<endl;
}
}
HJ25 数据分类处理 排序 较难 20.73%
HJ29 字符串加解密 字符串 较难 25.10%
题解:加密 和 解密 相加的数字等于模数即可
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
string res;
while(cin>>str>>res)
{
for(int i=0;i<str.length();i++)
{
if(str[i]<='9'&&str[i]>='0')
str[i]=(str[i]-'0'+1)%10+'0';
else if(str[i]<='Z'&&str[i]>='A')
str[i]=(str[i]-'A'+1)%26+'a';
else if(str[i]<='z'&&str[i]>='a')
str[i]=(str[i]-'a'+1)%26+'A';
cout<<str[i];
}
cout<<endl;
for(int i=0;i<res.length();i++)
{
if(res[i]<='9'&&res[i]>='0')
res[i]=(res[i]-'0'+9)%10+'0';
else if(res[i]<='Z'&&res[i]>='A')
res[i]=(res[i]-'A'+25)%26+'a';
else if(res[i]<='z'&&res[i]>='a')
res[i]=(res[i]-'a'+25)%26+'A';
cout<<res[i];
}
cout<<endl;
}
}
HJ30 字符串合并处理 字符串排序 较难 25.02%
题解:根据题意一步步做
#include<bits/stdc++.h>
using namespace std;
char judge(int change1)
{
char res;
if(change1==0) res+='0';
else if(change1==1) res+='1';
else if(change1==2) res+='2';
else if(change1==3) res+='3';
else if(change1==4) res+='4';
else if(change1==5) res+='5';
else if(change1==6) res+='6';
else if(change1==7) res+='7';
else if(change1==8) res+='8';
else if(change1==9) res+='9';
else if(change1==10) res+='A';
else if(change1==11) res+='B';
else if(change1==12) res+='C';
else if(change1==13) res+='D';
else if(change1==14) res+='E';
else if(change1==15) res+='F';
return res;
}
int main()
{
string str1;
string str2;
while(cin>>str1>>str2)
{
//处理步骤1
string temp=str1+str2;
//cout<<temp;
//处理步骤2
string record0="";
string record1="";
for(int i=0;i<temp.length();i++)
{
if(i%2==0) record0+=(temp[i]);
else record1+=(temp[i]);
}
sort(record0.begin(),record0.end());
sort(record1.begin(),record1.end());
string temp1="";int m=0,n=0;
for(int i=0;i<temp.length();i++)
{
if(i%2==0) temp1+=record0[m++];
else temp1+=record1[n++];
}
//cout<<temp1<<endl;
//处理步骤3
string temp2="";
for(int i=0;i<temp1.length();i++)
{
if(temp1[i]<='9'&&temp1[i]>='0')
{
int change1=temp1[i]-'0';
int change2[4]={(change1/8)%2,(change1/4)%2,(change1/2)%2,change1%2};
change1=0;
for(int i=0;i<4;i++) change1+=change2[i]*pow(2,i);
temp2+=judge(change1);
}
else if(temp1[i]<='F'&&temp1[i]>='A')
{
int change1=temp1[i]-'A'+10;
int change2[4]={(change1/8)%2,(change1/4)%2,(change1/2)%2,change1%2};
change1=0;
for(int i=0;i<4;i++) change1+=change2[i]*pow(2,i);
temp2+=judge(change1);
}
else if(temp1[i]<='f'&&temp1[i]>='a')
{
int change1=temp1[i]-'a'+10;
int change2[4]={(change1/8)%2,(change1/4)%2,(change1/2)%2,change1%2};
change1=0;
for(int i=0;i<4;i++) change1+=change2[i]*pow(2,i);
temp2+=judge(change1);
}
else temp2+=temp1[i];
}
cout<<temp2<<endl;
}
}
HJ32 密码截取 字符串 较难 26.13%
题解:就是求最长回文数,没有什么特别大的区别
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
while(cin>>str)
{
int max=0;
int startIndex=0;
//假设是abba偶数形式
for(int i=0;i<str.length();i++)
{
int m=i,n=i+1;
while(m>=0&&n<str.length()&&str[m]==str[n])
{
if(n-m+1>max)
{
max=n-m+1;
startIndex=m;
}
m--;
n++;
}
}
//假设是aba奇数形式
for(int i=0;i<str.length();i++)
{
int m=i-1,n=i+1;
while(m>=0&&n<str.length()&&str[m]==str[n])
{
if(n-m+1>max)
{
max=n-m+1;
startIndex=m;
}
m--;
n++;
}
}
cout<<max<<endl;
}
}
⭐⭐HJ33 整数与IP地址间的转换 字符串 较难 28.65%
题解:
- 难点在于理解左移和右移,在使用移位运算符时,自动进行了2-10-2的进制转化。
- 观察题目发现,10.0.3.193 对应ip地址00001010 00000000 00000011 11000001 10左移了24位,0左移了16位,3左移了8位,193没有移动,因此用移位运算符将这四个加起来就是最终的十进制数
- 而对于十进制数转成ip地址,利用右移,右移24位只有a不为0,其他以此类推,最终等到切分的ip十进制地址
#include <iostream>
using namespace std;
int main()
{
long long int a,b,c,d;
long long int num;
char dot;
while(cin>>a>>dot>>b>>dot>>c>>dot>>d){
cin>>num;
cout<<(a<<24)+(b<<16)+(c<<8)+d<<endl;
a = num>>24;
num = num-(a<<24);
b = num>>16;
num = num-(b<<16);
c = num>>8;
d = num-(c<<8);
cout<<a<<"."<<b<<"."<<c<<"."<<d<<endl;
}
}
HJ39 判断两个IP是否属于同一子网 字符串模拟 较难 16.43%
HJ41 称砝码 字符串 较难 37.03%
⭐HJ42 学英语 字符串 较难 28.37%
题解:每三位为一个循环,每三位后用的都是相同的内容
#include <bits/stdc++.h>
using namespace std;
vector<string> other = {"zero","one","two","three","four", \
"five","six","seven","eight","nine",\
"ten","eleven","twelve","thirteen","fourteen",\
"fifteen","sixteen","seventeen","eighteen","ninteen"};
vector<string> ften = {"none","ten","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"};
string englishnum(int num)
{//每三位是一个变化基准
if(num>=0&&num<=19)
return other[num];
else if(num>=20&&num<=99){
if(num%10==0)
return ften[num/10];
return ften[num/10]+" "+englishnum(num%10);
}
else if(num>=100&&num<=999){
if(num%100==0){
return other[num/100]+" hundred";
}else{
return other[num/100]+" hundred and "+englishnum(num%100);
}
}
else if(num>=1000&&num<999999){
if(num%1000==0)
return other[num/1000]+" thousand";
return englishnum(num/1000)+" thousand "+englishnum(num%1000);
}
else if(num>=1000000&&num<9999999)
{
if(num%1000000==0)
return other[num/1000000]+" million";
return other[num/1000000]+" million "+englishnum(num/1000%1000)+" thousand "+englishnum(num%1000);
}
else if(num>=10000000){
if(num%1000000000==0)
return other[num/1000000000]+" billion";
return englishnum(num/1000000000)+" billion "+englishnum(num%10000000/1000000)+" million "+englishnum(num%1000000/1000)+" thousand "+englishnum(num%1000);
}
else return "";
}
int main()
{
int n(0);
while(cin>>n){
cout<<englishnum(n)<<endl;
n=0;
}
return 0;
}
HJ51 输出单向链表中倒数第k个结点 链表 较难 24.28%
HJ58 输入n个整数,输出其中最小的k个 数组 较难 30.11%
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m;
while(cin>>n>>m)
{
int temp;
int num=n;
vector<int> record;
while(num--)
{
cin>>temp;
record.push_back(temp);
}
sort(record.begin(),record.end());
//reverse(record.begin(),record.end());
for(int i=0;i<m;i++)
{
cout<<record[i];
if(i!=m-1) cout<<" ";
else cout<<endl;
}
}
}
HJ68 成绩排序 排序 较难 23.51%
HJ77 火车进站 栈 较难 42.27%
HJ80 整型数组合并 数组排序 较难 30.46%
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m;
while(cin>>n)
{
set<int>record;
while(n--)
{
int temp;
cin>>temp;
record.insert(temp);
}
int m;cin>>m;
while(m--)
{
int temp;
cin>>temp;
record.insert(temp);
}
set<int>::iterator it=record.begin();
for(;it!=record.end();it++)
cout<<(*it);
cout<<endl;
}
}
HJ81 字符串匹配 字符串 较难 28.11%
题解:
- 注意不是字符串匹配
- 是看子串中的所有字符是不是在长串中出现
- 使用map
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str1;
string str2;
while(cin>>str1>>str2)
{
if(str1.length()>str2.length()) swap(str1,str2);
//cout<<str1<<endl;
//cout<<str2<<endl;
map<char,int>map1;
map<char,int>map2;
for(int i=0;i<str1.length();i++)
map1[str1[i]]=1;
for(int i=0;i<str2.length();i++)
map2[str2[i]]=1;
int flag=1;
for(int i='a';i<'z';i++)
{
if(map1[i]&&map1[i]!=map2[i])
{
flag=0;
break;
}
}
if(flag) cout<<"true"<<endl;
else cout<<"false"<<endl;
}
}
HJ92 在字符串中找出连续最长的数字串 字符串 较难 27.75%
//先找出最长的长度,然后用同样的方法输出子串就可以了
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
while(cin>>str)
{
vector<int>startIndex;
int max=0;
vector<int>start;
for(int i=0;i<str.length();i++)
{
int m=i;
while(m<str.length()&&str[m]<='9'&&str[m]>='0')
{
m++;
if(m-i+1>max) max=m-i;
}
}
for(int i=0;i<str.length();i++)
{
int m=i;
while(m<str.length()&&str[m]<='9'&&str[m]>='0')
{
m++;
if(m-i==max)
{
for(int j=i;j<m;j++) cout<<str[j];
}
}
}
cout<<","<<max<<endl;
}
}
HJ93 数组分组 字符串递归 较难 30.23%
HJ94 记票统计 较难 26.11%
题解:根据题意做就行了
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
vector<string> record;
int temp=n;
string tempS;
while(temp--)
{
cin>>tempS;
record.push_back(tempS);
//cout<<tempS;
}//cout<<endl;
int vote; cin>>vote;temp=vote;
vector<string> compare;
while(temp--)
{
cin>>tempS;
compare.push_back(tempS);
//cout<<tempS;
}//cout<<endl;
vector<int> flagRecord(record.size(),0);
vector<int> flagCompare(compare.size(),0);
for(int i=0;i<record.size();i++)
{
for(int j=0;j<compare.size();j++)
{
if(compare[j]==record[i])
{
flagRecord[i]++;
flagCompare[j]=1;
}
}
cout<<record[i]<<" : "<<flagRecord[i]<<endl;
}
int invalid=0;
for(int j=0;j<compare.size();j++)
if(!flagCompare[j]) invalid++;
cout<<"Invalid : "<<invalid<<endl;
}
}
HJ95 人民币转换 字符串 较难 26.66%
HJ105 记负均正II 数组 较难 25.23%
HJ23 删除字符串中出现次数最少的字符 字符串
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
while(cin>>str)
{
//存储每个字符的度
map<char,int> map;
for(int i=0;i<str.length();i++)
map[str[i]]++;
//将最小的度找出来
int min=str.length();
for(int i=0;i<str.length();i++)
if(map[str[i]]<min) min=map[str[i]];
//将度不为最小的字符存储起来
vector<char> record;
for(int i=0;i<str.length();i++)
if(map[str[i]]!=min) record.push_back(str[i]);
//输出结果
for(int i=0;i<record.size();i++)
cout<<record[i];
cout<<endl;
}
return 0;
}
—————————————————————————————————————————————————————
HJ18 识别有效的IP地址和掩码并进行分类统计 字符串 困难 19.80%
HJ19 简单错误记录 字符串 困难 18.95%
HJ27 查找兄弟单词 困难 18.60%
HJ28 素数伴侣 排序 困难 24.33%
HJ44 Sudoku 搜索数学 困难 28.09%
HJ82 将真分数分解为埃及分数 搜索数学 困难 40.57%
🔺HJ89 24点运算 字符串模拟穷举 困难 20.12%
题解:不会,知道用dfs但是我不会写,参考别人的修改AC如下
#include <iostream>
#include<string>
#include<string.h>
#include <algorithm>
using namespace std;
int num[4];
int signal;
string operations = "+-*/";
bool dfs(int start,int sum)
{
if (start==4&&sum == 24)
{
signal = 1;
for (int i = 0; i < 4; i++)
{
if(num[i]<=10&&num[i]>=2) cout << num[i];
else if(num[i]==1) cout<<"A";
else if(num[i]==11) cout<<"J";
else if(num[i]==12) cout<<"Q";
else if(num[i]==13) cout<<"K";
if(i!=3)cout<<operations[i];
if(i==3) cout<<endl;
}
return true;
}
for (int i =start; i < 4; i++)
{
if (!signal) {
operations[start - 1] = '+';
dfs(start + 1, sum + num[start]);
}
if (!signal) {
operations[start - 1] = '-';
dfs(start + 1, sum - num[start]);
}
if (!signal) {
operations[start - 1] = '*';
dfs(start + 1, sum * num[start]);
}
if (!signal) {
operations[start - 1] = '/';
dfs(start + 1, sum / num[start]);
}
}
return signal;
}
int main()
{
string str[4], strData = " A234567891JQK";
while (cin>>str[0]>> str[1] >> str[2] >> str[3] )
{
int error = 0;
signal = 0;
for (int i=0;i<4;i++)
{
if (str[i] == "10") num[i] = 10;
else
if (strData.npos == strData.find(str[i]))
{
error = 1;
cout << "ERROR" << endl;
break;
}
else num[i] = strData.find_first_of(str[i]);
}
if (!error)
{
do
{
if (dfs(1, num[0])) break;
} while (next_permutation(num, num + 4));
if (!signal) cout << "NONE" << endl;
}
}
return 0;
}
HJ31 单词倒排 字符串排序 困难 19.80%
题解:将不是空格且不是字母的字符转变为空格符进行处理
在这里插入代码片
445

被折叠的 条评论
为什么被折叠?



