集合篇7:华为机试(刷题记录)

1.两数的最小公倍数

题目
最小公倍数=两数之乘除以其最大公因数;
方法一:笨方法:先找最大公因数

int maxFactor(int num1,int num2)
{
   
    if(num1<=0 || num2<=0)
        return 0;
    int max=0;
    if(num1%num2==0 || num2%num1==0)
    {
      max=num1<num2?num1:num2;
        return max;
    }
    int temp=num2>num1?num1:num2;
    for(int i=1;i<=temp/2;i++)
    {
   
        if( num1%i==0 && num2%i==0 && i>max)
            max=i;
    }
    return max;
}

方法二:

//while(scanf("%d\n%d",&a,&b)!=EOF) //循环输入测试用例
fflush(stdin); //清除标准输入的内容;学到了
int i=1if(a<b) //交换ab;
while(1){
   
if((i*a)%b==0) //输出返回结束;
i++;
}

2.求一个数的立方根

题目
方法一:笨方法

double getCubeRoot(double num)
{
   
    double a=1.0;
    for(double i=1.0;i<num/3;i=i+a)
    {
   
        //if(i*i*i==num)
        if(num-i*i*i<1e-4 && 0<num-i*i*i) //该处和下面的if判断任选其一;
        {
   
            return i;
        }
        else if(i*i*i>num)
        {
   
            i=i-1*a; //类似于深度学习的学习率
            a=a/10.0;
            //if(a<0.001)  //疑惑为什么不加入该判断时,将进入死循环,
            //    return i;
        }
    }
    return -1;
}
 cout<<setprecision(2)<<res<<endl; //输出保留两位有效数字;

方法二:数学方法、牛顿迭代公式

#include<bits/stdc++.h>
using namespace std;
int main()
{
   
    int input;
    while(cin>>input)
    {
   
        double x=1.0;
        for(;abs(x*x*x-input)>1e-4;x=2*x/3+input/(3*x*x));
        //根据牛顿迭代公式:
        //平方根:x=x/2+input/(2*x);
        //立方根:x=2*x/3+input/(3*x*x));
        cout<<setprecision(2)<<x<<endl;
    }
    return 0;
}

3.字符串逆序

题目
本题不难,就是在如何读取数据上注意一下

//读取字符
char ch[1001];
cin.getline(ch,1000);
//读取一行赋值给字符串
string str;
getline(cin,str);
//一行读取n个数
while(cin>>a)
{
   
	vec.push_back(a);
	if(cin.get()=='\n')
		break;
}

4.统计正均负数II

题目1

题目2
题目分类较难;但是我感觉一般,所以不要被题目分类吓住;

//感觉需要主要如何控制输出精度,以下保留小数点后一位
    printf("%0.1f",res);
    cout<<fixed<<setprecision(1)<<res<<endl;

5.字符串划分

题目
下面的方法不通过原因:因为系统后台要测试多组数据如果这写,那么将只测试一组,导致输入后面测试用例时,输出为空; ---->在这卡了半天;
将cin>>n改为while(cin>>n)即可;

#include <bits/stdc++.h>
using namespace std;
int main()
{
   
    int n;
    cin>>n;
    string str;
    while(n-->0)
    {
   
        cin>>str;
        int i=0;
        for(;i<str.size();i++)
        {
   
            cout<<str[i];
            if((i+1)%8==0)
                cout<<endl;
        }
        if(i%8!=0){
   
        while(i%8!=0)
            cout<<"0",i++;
        cout<<endl;
        }
    }
    return 0;  
}

可以对上面进行简单改进,循环判断时,每次加8,这这样处理一个字符串的时间就缩小了8倍;

6.最长递增子序列(not)

题目
方法一:使用两个数组,一个保持原始数据,一个保持排序好的;然后对两个数组使用动态规划(类似最长公共子序列的求法),但是这里有重复的数字,所以最后再用dp[n][n]-重复的数据; ------->但是结果不对,不符号最长公共子序列的形式;
对上面的修改:我先根据排序好的数组numbak对numbak和nums进行去重,去重规则为每次取出最前面相同的那个数;然后再对去重后的数组进行动态规划(注意此时动态数组的len已经改变,变小了);------->通过率为60%;

  • 我知道问题原因了:再对数组去重时,先去前面的,导致这种情况:1 2 3 61 5 7去重后 2 3 6 1 5 7了,最长递增子序列由5变为7,我也考虑由后往前去重,同样会出现那些的问题;
//inline int max1(int a,int b)省略、篇幅太长了
int main()
{
   
    int n;
    while(cin>>n){
   
    int a;
    vector<int> nums;
    vector<int> numbak;
    for(int i=0;i<n;i++)
    {
      cin>>a;
        nums.push_back(a);
        numbak.push_back(a);
    }
    sort(nums.begin(),nums.end());
    for(int i=0;i<nums.size()-1;i++)
    {
   
        vector<int>::iterator iter;
        if(nums[i]==nums[i+1])
        {
     
            for(int j=0;j<numbak.size();j++)
            {
   
                if(numbak[j]==nums[i])
                {
   
                    iter=find(numbak.begin(),numbak.end(),numbak[j]);  
                    numbak.erase(iter);
                    break;
                }
            }
            iter=find(nums.begin(),nums.end(),nums[i]);
            i--; //因为每次删除一个元素,nums.size()都会变小,所以保持i不变
            nums.erase(iter);
        }
    }
    int len=nums.size();
    int arr[len+1][len+1];
    for(int i=0;i<len+1;i++)
    {
   
        arr[0][i]=0,arr[i][0]=0;
    }
    for(int i=1;i<len+1;i++)
        for(int j=1;j<len+1;j++)
        {
   
            if(nums[i-1]==numbak[j-1])
                arr[i][j]=arr[i-1][j-1]+1;
            else
                arr[i][j]=max1(arr[i-1][j],arr[i][j-1]);
        }
    int res=arr[len][len];
    cout<<res<<endl;
 }
 return 0;
}

方法二:大神的写法,真是厉害;二分查找法;

int main()
{
   
    int n;
    while(cin>>n)
    {
   
        vector<int> vec;
        int a;
        for(int i=0;i<n;i++)
        {
      
          //vec的数据一定是有序的
            cin>>a;
            if(vec.size()==0)
                vec.push_back(a);
            else if(lower_bound(vec.begin(),vec.end(),a)==vec.end())
                vec.push_back(a);
         //如果a[i]不在res.begin()到res.end()之间,即a[i]比res每个数都大;如vec;
            else  //否则,表明a[i]在上述范围内,返回第一个>=a[i]的那个数的迭代器;
                *(lower_bound(vec.begin(),vec.end(),a))=a;
        }
        cout<<vec.size()<<endl;
    }
    return 0;
}
//二插查找算法三种:
//1.lower_bound(起始地址,结束地址,要查找的数值为a) 返回的是数值 第一个 出现的位置。
//lower_bound如果a<结束地址值,但是没有与a相等的,就返回第一个比a大元素的迭代器;即>=a的那个数的迭代器;
//如在2,7查找1:将返回2的迭代器; 在1 4 7中查找5,将返回7的迭代器;
//2.upper_bound(起始地址,结束地址,要查找的数值) 返回的是数值 最后一个 出现的位置。
//3.binary_search(起始地址,结束地址,要查找的数值)  返回的是是否存在这么一个数,是一个bool值。

方法三:动态规划
和我想一起去了,只是我没实现出来,很可惜,dp[i]为前面比它小的那个数的dp[i];

int main()
{
   
    int n;
    while(cin>>n)
    {
   
        int a[n];
        for(int i=0;i<n;i++)
            cin>>a[i];
        vector<int> res(n,1);
        int maxcount=n>0?1:0;
        for(int i=1;i<n;i++)
        {
   
            for(int j=0;j<i;j++)
                if(a[j]<a[i])
                    res[i]=max(res[i],res[j]+1);
            if(res[i]>maxcount)
                maxcount=res[i];
        }
        cout<<maxcount<<endl;
    }
    return 0;
}

7.统计字符(not)

题目
方法一:双哈希法,因为题目要求要是两个字符数量一样,需要按ASCLL码(128位)进行打
印;
这类题目做的相对较少;双排序;

int main()
{
   
    char str[60000];
    int len=0;
    while(cin>>str)
    {
   
        int hash[128]={
   0};//为了完成对统计数的排序
        int hash2[128]={
   0}; //为了打印时与hash进行映射
        len=strlen(str);
        for(int i=0;i<len;i++)
            hash[str[i]]++, hash2[str[i]]++;
        sort(hash,hash+128);//排序数据后0 0 0... 0 0 1 2 3....
        sort(str,str+len); //
        //对字符串排序按ASCLL码排序,为了处理相同数量按ASCLL打印;
        for(int i=127;i>=0;i--)
        {
   
            if(hash[i]==0) break;
            for(int j=0;j<len;j++)
            {
    //如果该字符的出现的次数hash2[str[j]]等于最大次数hash[i]
                if(hash2[str[j]]==hash[i])
                {
   
                    cout<<str[j]; //输出字符
                    hash2[str[j]]=0; //清除该字符的统计数量,因为如果后面的字符数量也为hash2[str[j]],那么打印的就是str[j]了,重复打印;
                    break;
                }               
            }
        }
        cout<<endl;
    }
   return 0;
}

8.输入整型数组和排序标识,对其元素按照升序或降序进行排序

题目
注意题目中的输入细节:
先输入一个数
再输入一行数
再输入表示tag(0或1)

//可以调用STL的函数sort更快
sort(v1.begin(),v1.end()); //greater<int>(),less<int>();
int arr[n];
sort(arr,arr+n);
//反转
reverse(v1.begin(),v1.end(
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
108题中有部分题目重合,因此么有收录在压缩文件中。 华为机试 ├─001 字符串最后一个单词长度 │ └─Source ├─002 计算字符个数 │ └─Source ├─003 明明的随机数 │ └─Source ├─004 字符串分隔 │ └─Source ├─005 进制转换 │ └─Source ├─006 质数因子 │ └─Source ├─007 取近似值 │ └─Source ├─008 合并表记录 │ └─Source ├─009 提取不重复的整数 │ └─Source ├─010 字符个数统计 │ └─Source ├─011 数字颠倒 │ └─Source ├─012 字符串反转 │ └─Source ├─013 句子逆序 │ └─Source ├─014 字典序排序 │ └─Source ├─015 求int型正整数在内存中存储是1的个数 │ └─Source ├─016 购物单 │ ├─Debug │ ├─Source │ │ └─Debug │ ├─Source - 时间优先 │ │ └─Debug │ └─Source - 空间优先 │ ├─Debug │ └─Release ├─017 坐标移动 ├─018 识别IP地址分类统计 │ └─Source │ └─Debug ├─019 错误记录 ├─020 密码验证合格程序 ├─021 密码破解 ├─023 删除字符串中出现次数最少字符 │ └─Source │ └─Debug ├─024 合唱队 │ └─Source │ ├─Debug │ └─Release ├─025 数据分类处理 │ └─Source │ └─Debug ├─026 查找兄弟单词 │ └─Source │ └─Debug ├─027 素数伴侣 │ └─Source │ └─Debug ├─028 字符串合并处理 │ └─Source │ └─Debug ├─030 密码截取(查找最长回文字符串) ├─031 蛇形矩阵 │ └─Source │ └─Debug ├─033 判断IP是否属于同一子网 │ └─Source │ └─Debug ├─034 称砝码 │ └─Source │ └─Debug ├─035 学英语 │ └─Source │ └─Debug ├─036 迷宫问题 │ └─Source │ └─Debug ├─037 数独问题 │ └─Debug ├─038 名字漂亮度 │ └─Source │ └─Debug ├─039 字符串截取 │ └─Source │ └─Debug ├─040 单链表删除数据 │ └─Source │ └─Debug ├─041 多线程 │ └─Source │ ├─Backup │ ├─Debug │ │ └─041.tlog │ └─Release │ └─041.tlog ├─042 表达式计算 │ └─Source │ └─Debug ├─043 计算字符串距离 │ └─Source │ └─Debug ├─044 杨辉三角形变形 ├─046 挑7 ├─047 完全数 │ └─Debug ├─048 高精度加法 ├─049 输出n个数中最小的k个 │ └─Debug ├─050 找出字符串只出现一次的字符 │ └─Debug ├─051 组成一个偶数最接近的2个质数 │ └─Debug ├─052 M个苹果放入N个盘子 ├─053 查找整数二进制中1的个数 ├─054 DNA子串 ├─055 MP3光标位置 │ └─Source │ └─Debug ├─056 查找2个字符串最大相同子串 │ └─Debug ├─057 配置文件恢复 │ └─Source │ └─Debug ├─058 24点计算 │ └─Debug ├─059 成绩排序 ├─060 矩阵相乘 ├─061 矩阵乘法次数计算 ├─062 字符串通配符 │ └─Debug ├─066 命令行解析 │ └─Source │ └─Debug ├─067 最大相同子串长度 │ └─Debug ├─068 火车编号进站 │ └─Debug ├─072 数组合并 ├─074 埃及分数 │ └─Source │ └─Debug ├─076 密码截取 │ └─Source ├─077 求最大连续bit数 ├─078 密码强度 ├─079 扑克牌大小 │ └─Source │ └─Debug ├─081 合法IP ├─082 棋盘格子走法 ├─083 在字符串中找出连续最长数字串 ├─084 int数组分组,两组和相等 │ └─Source │ └─Debug ├─086 人民币转换 │ └─Source │ └─Debug ├─087 表示数字 ├─090 自动售货系统 │ └─Source │ └─Debug └─091 24点输出 └─Debug

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值