华为机试在线训练|解题记录|HJ01-103

华为机试在线训练

0.基础知识

0.1.输入输出

0.1.1基础输入输出

  1. 输入正常普通的
int n;
cin>>n;
cout<<n;
  1. 输入带空格的
string str;
cin(cin,str);

0.1.2 头文件

  1. 通用头文件
#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)

substr参考

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.关于动态规划

  1. 动态规划初级
  2. 动态规划中级
  3. 中级最长递增子序列问题——动态规划
  • 子序列并不一定是连续的子串
  • 子串一定是连续的
  • 连续递增的子序列和前一个字符的最大递增长度
    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的个数
—————————————————————————————————————————————————————————————
解法:

  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 输入整型数组和排序标识,对其元素按照升序或降序进行排序

解题:

  1. 处理输入输出
  2. 找出空格所在的位置,并对字符串进行提取,转换成数字;其中第一个数字要特殊处理,最后一个也要特殊处理(可以通过将字符串长度推入假设为空格位置也可以切分)。
  3. 完成排序
#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%

HJ12 字符串反转

#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%

题解:

  1. 使用双栈,将数字和符号分开存储
  2. 遇到左括号,=-*/先压入栈,计算的情况由两种
  3. 一是遇到右括号时,开始对数字进行计算,每次使用一个符号,两个数字,计算出来的数字再压入栈
  4. 二是遇到要压入栈的符号,是同级优先度,或者的优先度大于
#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%

题解:

  1. 没有想到将计数和输出分开计算
  2. 没有想到用“”两个符号夹着输出,只想到考虑空格
#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%

HJ106 字符逆序

#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 求最小公倍数 递归 数学

题解:

  1. 分成两种情况:
  • 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%

题解:

  1. 利用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%

参考链接1-C++
参考链接2-理论

#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%

题解:

  1. 利用动态规划,比较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%

题解:

  1. 抓住两个条件 含’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%

题解:

  1. 处理特定长度的字符串即可,计算其中的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%

题解:

  1. 运用动态规划,处理问题,如果相等,在前一个的基础上加一;如果不相等,等于0,意味着没有相同子串,注意不等于1;
  2. 参考头部给出的几个动态规划的博客理解
  3. 注意是子串,不是子序列
#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%

题解:

  1. 处理输入输出,然后对着公式进行,注意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%

题解:

  1. 没有想到只有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%

题解:

  1. 关键先对字符串排序,这样就是按ascii码排序的,后面只用考虑度的问题了
  2. 用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%

题解:

  1. 使用set自动排序
  2. 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%

题解:

  1. 用一个外部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%

题解:

  1. 使用动态规划,从0-(n-1)考虑递增的,从(n-1)-0考虑递减的
  2. 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%

题解:

  1. 难点在于理解左移和右移,在使用移位运算符时,自动进行了2-10-2的进制转化。
  2. 观察题目发现,10.0.3.193 对应ip地址00001010 00000000 00000011 11000001 10左移了24位,0左移了16位,3左移了8位,193没有移动,因此用移位运算符将这四个加起来就是最终的十进制数
  3. 而对于十进制数转成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%

题解:

  1. 注意不是字符串匹配
  2. 是看子串中的所有字符是不是在长串中出现
  3. 使用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 删除字符串中出现次数最少的字符 字符串

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%

题解:将不是空格且不是字母的字符转变为空格符进行处理

在这里插入代码片
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值