• 微信公众号:美女很有趣。 工作之余,放松一下,关注即送10G+美女照片!

C语言每日一练(六)——华为机试

互联网 diligentman 3个月前 (03-19) 26次浏览

       C语言作为嵌入式Linux开发的必备工具,作为嵌入式Linux开发的基础语言,那么在面试嵌入式工程师时C语言定是面试中的重中之重 。作为一名大三的老学长,不得不为找工作做必要准备。每天做一道C语言面试,为面试打基础。
C语言每日一练(六)——华为机试

2021.02.18

       2021年的春节已经悄然过去,距离2022届暑假实习生招聘的钟声已经敲响!待3月开学回到学校后各大公司将陆续抛出大量的实习岗位,这正是为秋招做准备查漏补缺的大好时机,通过面试可以了解自己的不足、增加面试经验,如果获得暑假实习生的资格将有很大概率可以转正。据说某些公司的暑假实习生的转正比高达80%,因此准备暑假实习是非常有必要的。
       对于我来说如果实习能够去手机厂(华为、oppo、vivo、小米)或者行业独角兽(CVTE、海康威视、深信服、ARM中国、紫光展锐等)是最好的。我目前在一家手机ODM公司实习,岗位是驱动工程师,来了公司近一个月啦好像也没有学到什么技术,不过我倒是对公司的业务更加的清楚,更加理解了什么是ODM公司!公司主要的业务就是服务于各个手机、平板、手环等公司来完成一款产品的研发。当然手机厂的核心技术和核心代码是不会给的!主要的业务就是ODM公司的测试这个机器中存在的问题,然后将问题整理成问题单,是驱动的问题就返回给驱动,是应用层的问题就返回给应用层,然后驱动这边如果将问题复现就将问题返会给供货商,让供货商在下一版的固件中来解决这些问题。所以手机ODM公司可以认识到比较多的人,比如华为、oppo、小米、联发科、高通,因为公司得同时和供货商与服务商进行沟通交流。
       感觉这个岗位和我想象的差别挺大的,不过实习确实挺轻松,公司的福利待遇也很可以,朝九晚六还有加班费、餐补、车补、每月团建等。不过对于实习生我觉得还是不太重视对实习生的培养,来了公司没有系统的培训,就偶尔打打下手帮帮忙,然后就是坐在自己的座位上玩手机或者学习还有工资发!来公司配的32G+4T硬盘的电脑怎么能不好好利用一下呢!在公司带薪学习还是很不错的!

题目描述:
       输入一个int型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。保证输入的整数最后一位不是0。
输入描述:
       输入一个int型整数

输出描述:
       按照从右向左的阅读顺序,返回一个不含重复数字的新的整数

示例:

输入
9876673
输出
37689

题目解析:

#include <stdio.h>
int main()
{
    int n,m=0;
    scanf("%d",&n);
    int a[10]={0};
    while(n){
        if(a[n%10]==0)
        {
            a[n%10]++;
            m=m*10+n%10;
        }
        n/=10;
    }
    printf("%d",m);
    return 0;
}

2021.02.19

题目描述:
       现有一组砝码,重量互不相等,分别为m1,m2,m3…mn;
每种砝码对应的数量为x1,x2,x3…xn。现在要用这些砝码去称物体的重量(放在同一侧),问能称出多少种不同的重量。

注:
       称重重量包括0
输入描述:
       输入包含多组测试数据。

       对于每组测试数据:

       第一行:n — 砝码数(范围[1,10])

       第二行:m1 m2 m3 … mn — 每个砝码的重量(范围[1,2000])

       第三行:x1 x2 x3 … xn — 每个砝码的数量(范围[1,6])
输出描述:
       利用给定的砝码可以称出的不同的重量数

示例
输入
2
1 2
2 1
输出
5

题目解析:
       拿到题目的一瞬间很容易想到是用排列组合的方法,但是更近一步应该如何进行排列组合呢?这就是一个难题!那么我们就可以使用一个比较大的数组,类似于桶排序的思想。以第一个砝码为基础在其基础上不断的添加砝码!

#include <stdio.h>
#include <malloc.h>
#include <string.h>
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)//砝码数
    {
        int i,j,k,max=0,count=0;//每个砝码的重量m[i],每个砝码的个数x[i]
        int m[10]={0},x[10]={0};
        for(i=0;i<n;i++){
            scanf("%d",&m[i]);
        }
        for(i=0;i<n;i++){
            scanf("%d",&x[i]);
        }
        for(i=0;i<n;i++){
            max+=m[i]*x[i];//最大金额
        }
        int *array=(int *)malloc(sizeof(int)*(max+1));
        //int *array=(int *)malloc(sizeof(int)*(max+1));
        memset(array,0,sizeof(int)*(max+1));
        //int array[10000]={0};
        //printf("the sizeof(int *)(max+1) is %ld,the max is %dn",sizeof(int)*(max+1),max);
        array[0]=1;
        for(i=0;i<n;i++)
            for(j=0;j<x[i];j++)
                for(k=max;k>=0;k--)
                    if(array[k]==1)
                        array[k+m[i]]=1;
        for(i=max;i>=0;i--){
            if(array[i]==1)
                count++;
        }
        printf("%dn",count);
    }
}

       上面的代码可以清晰的看出来用了3重循环,第一重循环用于记录砝码的种类,第二重循环用来记录每种砝码对应的个数,第三重循环用来遍历和标记添加砝码后的质量。当然很多小伙伴会疑惑为什么第三重循环得从max减小到0,为什么不从0增加到max呢?其实仔细思考后就会发现问题!当我们从0到max当发现一个标志位为1的之后又使array[k+m[i]]变为1,再然后k++就再次遇见了之前的array[k+m[i]]又得再改变他之后的标志位。这样就会导致增加大量的多余的标志信息,从而导致结果错误。现在再想想如果是倒叙遍历的话就不会出现这种情况!

2021.02.21

题目描述
       蛇形矩阵是由1开始的自然数依次排列成的一个矩阵上三角形。

       例如,当输入5时,应该输出的三角形为:

1 3 6 10 15

2 5 9 14

4 8 13

7 12

11

       请注意本题含有多组样例输入。

输入描述:
       输入正整数N(N不大于100)

输出描述:
       输出一个N行的蛇形矩阵。

示例

输入:
4
输出:
1 3 6 10
2 5 9
4 8
7

题目解析:

#include <stdio.h>
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF){
        int i,j,count=0,arr[101]={0};
        arr[0]=1;
        for(i=1;i<=n;i++){
            arr[i]=arr[i-1]+i-1;
            printf("%d ",arr[i]);
            count=arr[i];
            for(j=1;j<=n-i;j++){
                count=count+j+i;
                printf("%d ",count);
            }
            printf("n");
        }
    }
    return 0;
}

2021.02.23

题目描述:
       Jessi初学英语,为了快速读出一串数字,编写程序将数字转换成英文:

       如22:twenty two,123:one hundred and twenty three。

说明:

       数字为正整数,长度不超过九位,不考虑小数,转化结果为英文小写;

       输出格式为twenty two;

       非法数据请返回“error”;

       关键字提示:and,billion,million,thousand,hundred。

       本题含有多组输入数据。

输入描述:
       输入一个long型整数

输出描述:
       输出相应的英文写法

示例:

输入
2356
输出
two thousand three hundred and fifty six

题目解析:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

const char num1[][12]={"zero","one","two","three","four","five","six","seven","eight","nine"};
const char num2[][12]={"ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"};
const char num3[][12]={"zero","ten","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"};
void judge(int n)
{
    if(n>=0&&n<10)
    {
        printf("%s",num1[n]);
    }
    else if(n>=10&&n<20)
    {
        printf("%s",num2[n-10]);
    }
    else if(n>=20&&n<100)
    {
        if(n%10==0)
             printf("%s",num3[n/10]);
        else
            printf("%s %s",num3[n/10],num1[n%10]);
    }
    else if(n>=100&&n<1000)
    {
        if(n%100==0)
            printf("%s hundred",num1[n/100]);
        else
        {
            printf("%s hundred and ",num1[n/100]);
            judge(n%100);
        }
    }
    else if(n>=1000&&n<1000000)
    {
        if(n%1000==0)
        {
            judge(n/1000);
            printf(" thousand");
        }
        else{
            judge(n/1000);
            printf(" thousand ");
            judge(n%1000);
        }
    }
    else{
        if(n%1000000==0)
        {
            judge(n/1000000);
            printf(" million ");
        }
        else
        {
            judge(n/1000000);
            printf(" million ");
            judge(n%1000000);
        }
    }
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        if(n<0||n>999999999)
            printf("error");
        else
        {
             judge(n);
            printf("n");   
        }
    }
    return 0;
}

       通过题目可以看出定义了三个数组,然后列出了一些基本的数字单词。在judge函数中通过不断的递归调用和判断来得到最终结果,只要想清楚了具体的代码实现还是很简单的。不过值得注意的是在我编写代码时发现函数judge不能拥有返回值在牛客的平台上。

2021.02.26

题目描述:
       对字符串中的所有单词进行倒排。

说明:

  • 1、构成单词的字符只有26个大写或小写英文字母;

  • 2、非构成单词的字符均视为单词间隔符;

  • 3、要求倒排后的单词间隔符以一个空格表示;如果原字符串中相邻单词间有多个间隔符时,倒排转换后也只允许出现一个空格间隔符;

  • 4、每个单词最长20个字母;

输入描述:
       输入一行以空格来分隔的句子

输出描述:
       输出句子的逆序

示例1:

输入
I am a student
输出
student a am I

题目解析:
       当拿到题目的时候我就想到之前有刷到类似的题目应该比较简单,我记得在看《剑指offer》时有关于这道题目的解法就是把字符串整体的给逆序,然后再把逆序后的字符串中的单词给再次逆序就达到了最终的效果。但是在测试的时候一直无法通过程序的测试样例具体原因还不太清楚。不过通过这道题目让我知道了很多的注意事项!在使用字符串输入函数时能不使用gets函数就不使用gets函数,因为这道题目我使用gets函数会导致段错误,把gets换成fgets就会好很多,但是换了fgets以后就导致了一个新问题——会将回车也给录入到字符串中,而且在使用strlen函数时会导致将换行符也给算进去就比较麻烦!最后在本地测试是可以实现相关功能的,但是在牛课上就出现了问题。
       后来我在一个嵌入式技术交流群里找到了这道题目的答案,想法很简单,就是利用二维数组!数组的每一行顺序保存一个单词,然后倒序输出就可以啦!

#include<stdio.h>
#include<string.h>
int main(void){
    char str[300][210],temp[2001];
    int n = 0,len=0,i,j=0;
    memset(str,0,sizeof(str));
    while(fgets(temp,sizeof(temp),stdin)){
        len=strlen(temp);
        n = 0;
        j = 0;
        for(i=0;i<len;i++){
            if((temp[i] >= 'a' && temp[i]<= 'z') || (temp[i] >= 'A' && temp[i]<= 'Z' )){
                str[n][j] = temp[i];
                j++;
            }else if(j > 0){
                j=0;
                n++;
            }
        }
        for(i = n-1;i>0;i--){
            printf("%s ",str[i]);
        }
        printf("%sn",str[0]);
        memset(str,0,sizeof(str));
        memset(temp,0,sizeof(temp));
    }
    return 0;
}

2021.03.01

题目描述:
       子网掩码是用来判断任意两台计算机的IP地址是否属于同一子网络的根据。子网掩码与IP地址结构相同,是32位二进制数,其中网络号部分全为“1”和主机号部分全为“0”。利用子网掩码可以判断两台主机是否中同一子网中。若两台主机的IP地址分别与它们的子网掩码相“与”后的结果相同,则说明这两台主机在同一子网中。

示例:
I P 地址  192.168.0.1
子网掩码  255.255.255.0

转化为二进制进行运算:

I P 地址 11010000.10101000.00000000.00000001
子网掩码 11111111.11111111.11111111.00000000

AND运算
11000000.10101000.00000000.00000000

转化为十进制后为:
192.168.0.0

I P 地址  192.168.0.254
子网掩码  255.255.255.0

转化为二进制进行运算:

I P 地址 11010000.10101000.00000000.11111110
子网掩码 11111111.11111111.11111111.00000000

AND运算
11000000.10101000.00000000.00000000

转化为十进制后为:
192.168.0.0

       通过以上对两台计算机IP地址与子网掩码的AND运算后,我们可以看到它运算结果是一样的。均为192.168.0.0,所以这二台计算机可视为是同一子网络。

       输入一个子网掩码以及两个ip地址,判断这两个ip地址是否是一个子网络。若IP地址或子网掩码格式非法则输出1,若IP1与IP2属于同一子网络输出0,若IP1与IP2不属于同一子网络输出2。

输入描述:
       输入子网掩码、两个ip地址

输出描述:
       得到计算结果

示例1

输入
255.255.255.0
192.168.224.256
192.168.10.4
255.0.0.0
193.194.202.15
232.43.7.59
输出
1
2

题目解析:
       在拿到题目的时候思路应该还是很清晰的,输入的ip地址其实就是4个数字我们可以将这四个数字通过移位合并成一个数字,然后将两组ip与子网掩码进行与运算,如果得到的结果相等那么就说明这两个ip位于同一网段!当然除了判断是否相等外还有就是判断是否合法,ip地址好判断,但是子网掩码有要求就是必须是连续的1,那么我们可以将子网掩码进行取反然后与上自己加一,如果结果为0则说明1是连续的。可以借鉴剑指offer的连续的1的个数!

#include <stdio.h>
int judege(int arr1[],int arr2[],int sub[])
{
    for(int i=0;i<4;i++){
        if(arr1[i]>255||arr1[i]<0||arr2[i]>255||arr2[i]<0||sub[i]>255||sub[i]<0)
            return 1;
    }
    int ip1_sum,ip2_sum,sub_sum,k;
    sub_sum=(sub[0]<<24)+(sub[1]<<16)+(sub[2]<<8)+sub[3];
    if(sub_sum==0xffffffff||sub_sum==0){
        return 1;
    }
    k=(~sub_sum);
    if((k&(k+1))!=0)
        return 1;
    ip1_sum=(arr1[0]<<24)+(arr1[1]<<16)+(arr1[2]<<8)+arr1[3];
    ip2_sum=(arr2[0]<<24)+(arr2[1]<<16)+(arr2[2]<<8)+arr2[3];
    if((ip1_sum&sub_sum)==(ip2_sum&sub_sum)){
        return 0;
    }
    return 2;
}
int main()
{
    int sonip[4];
    while(scanf("%d.%d.%d.%d",&sonip[0],&sonip[1],&sonip[2],&sonip[3])!=EOF)
    {
        int ip1[4],ip2[4];
        scanf("%d.%d.%d.%d",&ip1[0],&ip1[1],&ip1[2],&ip1[3]);
        scanf("%d.%d.%d.%d",&ip2[0],&ip2[1],&ip2[2],&ip2[3]);
        int flag;
        flag=judege(ip1, ip2, sonip);
        printf("%dn",flag);
    }
    return 0;
}

2021.03.04

题目描述:

  • 连续输入字符串,请按长度为8拆分每个字符串后输出到新的字符串数组;
  • 长度不是8整数倍的字符串请在后面补数字0,空字符串不处理。

输入描述:

  • 连续输入字符串(输入多次,每个字符串长度小于100)

输出描述:

  • 输出到长度为8的新字符串数组
输入
abc
123456789
输出
abc00000
12345678
90000000

题目解析:

#include <stdio.h>
#include <string.h>
int main()
{
    char str[101];
    while(scanf("%s",str)!=-1)
    {
        int len=strlen(str);
        //printf("%dn",len);
        int i=0,count=0;
        if(len<=8)
        {
            for(i=0;i<len;i++)
            {
                printf("%c",str[i]);
            }
            for(i=len;i<8;i++)
            {
                printf("0");
            }
            printf("n");
        }
        else{
            for(i=0;i<len;i++)
            {
                printf("%c",str[i]);
                count++;
                if(count==8)
                {
                    printf("n");
                    count=0;
                }
            }
            if(count!=0)
            {
                for(i=count;i<8;i++)
                {
                    printf("0");
                }
                printf("n");

            }
        }
    }
    return 0;
}

2021.03.05

题目描述:

  • 字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

示例 1:

  • 输入: s = “abcdefg”, k = 2
    输出: “cdefgab”

示例 2:

  • 输入: s = “lrloseumgh”, k = 6
    输出: “umghlrlose”

题目解析:
       当拿到题目的时候,第一反应就是交换顺序,但是数组来交换顺序的话是非常麻烦的。那么我们可以用malloc开辟出来一段新的空间,编写一个函数将这个字符串分为两次有顺序的保存到我们开辟的这个空间中。然后就返回这个开辟空间的首地址就可以啦!

#include <stdio.h>
#include <string.h>
#include <malloc.h>
char* reverse_n(char *str,int n,int len)
{
    int k=0;
    char *res=malloc((len+1)*sizeof(char)); 
    for(int i=n;i<len;i++)
    {
        res[k]=str[i];
        printf("%c ",res[k]);
        k++;
    }
    for(int i=0;i<n;i++)
    {
        res[k]=str[i];
        k++;
    }
    res[k]='';
    return res;
}
int main()
{
    char s[]="abcd1234",*p;
    int n=0,len=strlen(s);
    scanf("%d",&n);
    p=reverse_n(s,n,len);
    puts(p);
}

2021.03.06

题目描述:
       数据表记录包含表索引和数值(int范围的正整数),请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照key值升序进行输出。

输入描述:
       先输入键值对的个数,然后输入成对的index和value值,以空格隔开

输出描述:
       输出合并后的键值对(多行)

示例1

输入
4
0 1
0 2
1 2
3 4
输出
0 3
1 2
3 4

题目解析:

#include<stdio.h>
#include<string.h>
int main()
{
    int data[1001]={0},i=0,n,a,b;
    memset(data,0,sizeof(data));
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%d %d",&a,&b);
        data[a]+=b;
    }
    for(i=0;i<sizeof(data)/sizeof(data[0]);i++)
    {
        if(data[i] != 0)
            printf("%d %dn",i,data[i]);
    }
    return 0;
}

2021.03.08

题目描述:
       写出一个程序,接受一个十六进制的数,输出该数值的十进制表示。

输入描述:
       输入一个十六进制的数值字符串。

输出描述:
       输出该数值的十进制字符串。不同组的测试用例用n隔开。

示例:

输入
0xA
0xAA
输出
10
170

题目解析:

#include <stdio.h>
#include <string.h>
#include <math.h>

int main()
{
    char buf[32];
    int i=0,len,val=0;
    while(fgets(buf,sizeof(buf),stdin)!=0)
    {
        len =strlen(buf);
        int bit=0,sum=0;
        for(i=len-2;i>1;i--){
            switch(buf[i])
            {
                case 'A': val=10;
                    break;
                case 'B': val=11;
                    break;
                case 'C': val=12;
                    break;
                case 'D': val=13;
                    break;
                case 'E': val=14;
                    break;
                case 'F': val=15;
                    break;
                default: val=buf[i]-'0';
            }
            sum+=val*pow(16,bit);
            ++bit;
        }
        printf("%dn",sum);
    }
}

       不积小流无以成江河,不积跬步无以至千里。而我想要成为万里羊,就必须坚持学习来获取更多知识,用知识来改变命运,用博客见证成长,用行动证明我在努力。
       如果我的博客对你有帮助、如果你喜欢我的博客内容,记得“点赞” “评论” “收藏”一键三连哦!听说点赞的人运气不会太差,每一天都会元气满满呦!如果实在要白嫖的话,那祝你开心每一天,欢迎常来我博客看看。
C语言每日一练(六)——华为机试


程序员灯塔
转载请注明原文链接:C语言每日一练(六)——华为机试
喜欢 (0)