华为机试题31-40记录

H32 密码截取

笨笨思路:
用双指针的思想,遍历每个字母,时间复杂度高,但是容易想,每次从第一个字母开始遍历,i从前往后,j从后往前,当字母相同时num++,将flag设置为true,然后i++,j–,再次比对,如果不同,则i回到最初位置,j继续向前,直到i=j获得首字母为k的最长子串,k遍历整个字符串,来寻找最优解

#include<bits/stdc++.h>
using namespace std;
int main(){
    string s;
    cin>>s;
    int len=0;
    for(int k=0;k<s.size();k++){
        int i=k,j=s.size()-1;
        int num=0;
        bool flag=false;
        
        while(i<j){
        while(s[j]!=s[i]&&flag==false){
            num=0;
            j--;
        }
        if(j==i){
            continue;
        }
        if(s[i]==s[j]){ 
            flag=true;
            if(i!=j){
                num+=2;
            }
            i++;
            j--;
            if(i==j){
                num+=1;
            }
        }
        else{
            i=k;
            flag=false;
            num=0;
        }
        }
        if(len<num){
            len=num;
        }
    }
    cout<<len<<endl;
}

快快思路:中心扩散法
我们可以遍历每个字符串每个位置,都以其为回文子串的中心,或是奇数长度子串的中心(从两边开始找),或是偶数长度的子串中心(以它左边和它一起),分别向两边扩散,只要这个过程中两边字符是相等的就可以继续,直到边界或者不相等,这就是以这个为中心的回文子串的长度,我们比较每一个中心找到最长即可。

#include<bits/stdc++.h>
using namespace std;
int main(){
    string s;
    cin>>s;
    int maxlen=0;
    for(int i=1;i<s.length();i++){
        int low=i-1,high=i;//偶数
        while(low>=0&&high<s.length()&&s[low]==s[high]){
            low--;
            high++;
        }
        maxlen=max(maxlen,high-low-1);
        //奇数个
        low=i-1,high=i+1;
        while(low>=0&&high<s.length()&&s[low]==s[high]){
            low--;
            high++;
        }
        maxlen=max(maxlen,high-low-1);
        
    }
    cout<<maxlen<<endl;
    return 0;
}

H33 整数与IP地址间的转换

笨蛋方法,一点一点转换

#include<bits/stdc++.h>
using namespace std;
string binary(int k){
    string s="";
    while(k){
        s+=to_string(k%2);
        k=k/2;
    }
    while(s.length()<8){
        s+='0';
    }
    reverse(s.begin(),s.end());
    return s;
}
int main(){
    string s;
    cin>>s;
    int k=0;
    vector<int> v;
    long long num=0;
    for(int i=0;i<s.length();i++){
        if(isdigit(s[i])){
            k=k*10+s[i]-'0';
        }
        else if(s[i]=='.'){
            v.push_back(k);
            k=0;
        }
    }
    v.push_back(k);
    for(int i=0;i<4;i++){
        string str;
        str=binary(v[i]);
        for(int j=0;j<8;j++){
            int l=(3-i)*8;
            //int m=str[j];
            num+=(str[j]-'0')*pow(2,l+7-j);
        }
    }
    cout<<num<<endl;
    long long x;
    cin>>x;
    string str2="";
    while(x){
        str2+=x%2+'0';
        x=x/2;
    }
    while(str2.length()<32){
        str2+='0';
    }
    reverse(str2.begin(),str2.end());
    vector<string> ip;
    string li;
    for(int i=0;i<str2.length();i+=8){
        int temp=0;
        for(int j=i;j<i+8;j++){
            temp+=(str2[j]-'0')*pow(2,i-j+7);
        }
        li+=to_string(temp)+'.';
    }
    int kol=li.find_last_of('.');
    li.erase(kol);
    cout<<li<<endl;
    return 0;
}

聪明方法:
直接接受的是四段int型

#include <iostream>
using namespace std;

int main()
{
    long long int a,b,c,d;
    long long int num;

    while(scanf("%lld.%lld.%lld.%lld",&a,&b,&c,&d)!=EOF){
        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;
    }
}

H35蛇形矩阵

#include<iostream>
#include<vector>
using namespace std;
 
int main(){
    int n;
        int k = 1; //起始元素为1
        for(int i = 1; i <= n; i++){ //遍历每一行
            cout << k << " ";  //输出每行首
            int temp = k;
            for(int j = i + 1; j <= n; j++){ //遍历本行的数
                temp += j; //每个数相差为j
                cout << temp << " ";
            }
            cout << endl;
            k += i; //下一行的首为这行首加上这行行号
    }
    return 0;
}

*H37 统计每个月兔子数量

在这里插入图片描述斐波那契数列,

第x月
11
21
32
43
55
68

f(n)=f(n-1)+f(n-2)

#include<bits/stdc++.h>
using namespace std;
int getSum(int n){
    if(n==1||n==2){//第一第二个月只有1只
        return 1;
    }
    return getSum(n-1)+getSum(n-2);
}
int main(){
    int n;
    cin>>n;
    cout<<getSum(n)<<endl;
    return 0;
}

H39 判断两个ip是否属于同一个子网

直接把ip分成四段输入vector数组的办法:

vector<int> ip1;
char c;
cin>>ip1[0]>>c>>ip1[1]>>c>>ip1[2]>>c>>ip1[3];//第一个ip地址
cin>>ip2[0]>>c>>ip2[1]>>c>>ip2[2]>>c>>ip2[3];//第二个ip地址

别人的方法:主要注意按位与&

#include <iostream>
#include <vector>
 
using namespace std;
 
int main()
{
    vector<int> mask(4,0);
    vector<int> ip1(4,0);
    vector<int> ip2(4,0);
    char c;
    while (cin>>mask[0]>>c>>mask[1]>>c>>mask[2]>>c>>mask[3])//输入掩码
    {
        int flag = -1;//结果
        cin>>ip1[0]>>c>>ip1[1]>>c>>ip1[2]>>c>>ip1[3];//第一个ip地址
        cin>>ip2[0]>>c>>ip2[1]>>c>>ip2[2]>>c>>ip2[3];//第二个ip地址
        for(int i=0;i<4;i++)//两个ip地址和掩码每一段都要在0-255之间
        {
            if(mask[i]<0 || mask[i]>255 || ip1[i]<0 || ip1[i]>255 ||ip2[i]<0 || ip2[i]>255)
            {
                flag = 1;//格式非法
                break;
            }
        }
        for(int i=0;i<3;i++)//掩码的网络号全为1,主机号全为0
        {
            if(mask[i]<255 && mask[i+1]>0)
            {
                flag = 1;
                break;
            }
        }
        if(flag==1)//格式非法,输出1
        {
            cout<<flag<<endl;
        }else{
            for(int i=0;i<4;i++)
            {
                if((mask[i]&ip1[i])!=(mask[i]&ip2[i]))//两个ip地址和掩码做AND操作
                {
                    flag = 2;
                    break;
                }else{//AND操作结果不相同
                    flag = 0;
                }
            }
            cout<<flag<<endl;
        }
    }
    return 0;
}

我的笨蛋方法

#include<bits/stdc++.h>
using namespace std;
int main(){
    string a,b,c;
    cin>>a>>b>>c;
    vector<int> mask;
    vector<int> ip1;
    vector<int> ip2;
    int x=0,y=0,z=0;
    for(int i=0;i<15;i++){
        if(isdigit(a[i])){
            x=x*10+a[i]-'0';
        }
        else{
            if(a[i]=='-'){
                cout<<"1"<<endl;
                return 0;
            }
            if(x>=0&&x<=255){
                mask.push_back(x);
        }
            else{
                cout<<"1"<<endl;
                return 0;
            } 
            x=0;
        }
            
            
        if(isdigit(b[i])){
            y=y*10+b[i]-'0';
        }
        else{
            if(b[i]=='-'){
                cout<<"1"<<endl;
                return 0;
            }
            if(y>=0&&y<=255){
            ip1.push_back(y);
        }
        else{
            cout<<"1"<<endl;
            return 0;
        }
            y=0;
            
        }
        
        if(isdigit(c[i])){
            z=z*10+c[i]-'0';
        }
        else{
            if(c[i]=='-'){
                cout<<"1"<<endl;
                return 0;
            }
            if(z>=0&&z<=255){
            ip2.push_back(z);
        }
            else{
            cout<<"1"<<endl;
            return 0;
        }
            z=0;
        } 
    }
    bool test=true;
    for(int i=0;i<4;i++){
        if(mask[i]!=255&&i!=3){
            i++;
            while(i<4){
                if(mask[i]==0){
                    i++;
                }
                else{
                    cout<<"1"<<endl;
                    return 0;
                }
            }
        }
    }
  
    string web1,web2;
    bool flag=true;
    for(int i=0;i<4;i++){
        if(mask[i]==255){
            if(ip1[i]!=ip2[i]){
                flag=false;
            }
        }
    }
    if(flag){
        cout<<"0"<<endl;
        return 0;
    }
    else cout<<"2"<<endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值