美文网首页
008-牛客机试题

008-牛客机试题

作者: 千转军师 | 来源:发表于2021-03-30 21:45 被阅读0次

    时间:2021年3月30日14:00:21

    网址:https://www.nowcoder.com/ta/huawei

    题目

    ==================================>1

    • 题目描述:计算字符串最后一个单词的长度,单词以空格隔开。
    • 输入描述:输入一行,代表要计算的字符串,非空,长度小于5000。
    • 输出描述:输出一个整数,表示输入字符串最后一个单词的长度。

    C语言

    #include <stdio.h>
    #define MAX_SIZE 5000
    int main(void)
    {
        int cnt, n, n_tmp;
        char ch;
        char *p = &ch;
        cnt = n = n_tmp = 0;
        while(1)
        {
            cnt ++;
            if(cnt >= MAX_SIZE)
            {
                printf("warning:out of range!\n");
                return -1;
            }
            if(n != 0)n_tmp = n;
            scanf("%c", p);
            if(ch == '\n')break;    
                else n ++;
            
            if(ch == ' ')n = 0;
        }
        if(n == 0)n = n_tmp;
        printf("%d", n);
        return 0;
    }
    

    c++

    #include <iostream>
    #include <string>
    using namespace std;
    #define MAX_SIZE 5000
    int main(void)
    {
        string  str;
        int i;
        int n, tmp;
        if(str.length() >= MAX_SIZE)
        {
            cout << "warning:out of range!" << endl;
            return -1;
        }
        getline(cin, str);
        n = tmp = 0;
        for(i = 0; i < str.length(); i++)
        {
            if(n != 0)
            {
                tmp = n;
            }
            n ++;
            if(str[i] == ' ')
            {
                n = 0;
            }
        }
        if(str[str.length() - 1] == ' ')
        {
            n = tmp;
        }
        cout << n << endl;
        return 0;
    }
    

    ==================================>2

    • 题目描述
      写出一个程序,接受一个由字母、数字和空格组成的字符串,和一个字母,然后输出输入字符串中该字母的出现次数。不区分大小写。
    • 输入描述:
      第一行输入一个由字母和数字以及空格组成的字符串,第二行输入一个字母。
    • 输出描述:
      输出输入字符串中含有该字符的个数。
    #include <stdio.h>
    #include <string.h>
    #define MAX_SIZE 1024
    int main(void)
    {
        char buf[MAX_SIZE];
        char *p = buf;
        char ch, ch_tmp;
        int cnt;
        int i;
        int num;
        cnt = 0;
        while(1)
        {
            cnt++;
            if(cnt >= MAX_SIZE)
            {
                printf("warning:out of range!\n");
                return -1;
            }
            scanf("%c", p++);
            if(*(p - 1) == '\n')break;          
        }
        scanf("%c", &ch);
        num = 0;
        for(i = 0; i < cnt - 1; i++)
        {
            ch_tmp = buf[i];
            if(ch_tmp >= 'A' && ch_tmp <= 'Z')
            {
                ch_tmp -= 'A' - 'a';
            }
            if(ch >= 'A' && ch <= 'Z')
            {
                ch -= 'A' - 'a'; 
            }
            if(ch == ch_tmp)num++;
        }
        printf("%d", num);
        return 0;
    }
    

    ==================================>3

    明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤1000),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作(同一个测试用例里可能会有多组数据(用于不同的调查),希望大家能正确处理)。

    注:测试用例保证输入参数的正确性,答题者无需验证。测试用例不止一组。
    当没有新的输入时,说明输入结束。

    #include <stdio.h>
    
    void getNum(int *p, int n)
    {
        int i;
        for(i = 0; i < n; i++)
        {
            scanf("%d", p++);
        } 
    }
    int noRepead(int *p, int n)//返回查重后的数字个数
    {
        int i, j;
        int num;
        int pos1, pos2;
        num = 1;
        for(i = 1; i < n; i++)
        {
            for(j = 0; j < num; j++)
            {
                if(*(p + i) == *(p + j))
                {
                    break;
                }
                if(j == num - 1)
                {
                    *(p + num) = *(p + i);
                    num++;
                    break;
                }
            }     
        }
        return num;
    }
    
    void sortNum(int *p, int n)
    {
        int i, j;
        for(i = n - 1; i > 0; i--)
        {
            for(j = 0; j < i; j++)
            {
                if(*(p + j) > *(p + j + 1))
                {
                    *(p + j) ^= *(p + j + 1);
                    *(p + j + 1) ^= *(p + j );
                    *(p + j) ^= *(p + j + 1);
                }
            }      
        }  
    }
    
    void printArray(int *p, int n)
    {
        int i;
        for(i  = 0; i < n ; i++)
        {
            printf("%d\n", *(p + i));
        }
    }
    int main(void)
    {
        int num = 7;
        int num_array[num];
        getNum(num_array, num);
        num = noRepead(num_array, num);
        sortNum(num_array, num);
        printArray(num_array, num);
        return 0;
    }
    

    他人的思想借鉴:位图占用法。即用连续的1-1000二级制位来代表可能的数字,0代表无,1代表有;

    #include <stdio.h>
    
    void getNum(int *p, int n)
    {
        int i;
        for(i = 0; i < n; i++)
        {
            scanf("%d", p++);
        } 
    }
    
    
    int main(void)
    {
        int num = 5;
        int num_array[num];
        int i;
        unsigned char data[1001/8 + 1] = {0};
        getNum(num_array, num);
        for(i = 0; i < num; i++)
        {
            data[num_array[i] / 8] |= ((unsigned char)1) << (num_array[i] % 8); 
        }
        for(i = 0; i < 1001; i++)
        {
            if(data[i / 8] & ((unsigned char)1) << (i % 8))
            {
                printf("%d\n", i );
            }       
        } 
        return 0;
    }
    

    ==================================>4

    题目描述

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

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

    输出描述:

    输出到长度为8的新字符串数组

    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
        int str_num = 2;
        char buf[64][8] = {{0},};
        int i,j, k;
        char str[100] = {0};
        int idx;
        char *buf_p = buf[0];
        int len;
        idx = 0;
        for(i = 0; i < str_num; i++)
        {
            gets(str);
            len = strlen(str);
            j = 0;
            while(str[j] != '\0')
            {
                *(buf_p + idx + j) = str[j];
                j++;            
            }
            if(len % 8 != 0)
            {
                for(j = 0; j < (8 - (len % 8)); j++)
                {
                    *(buf_p + idx + len + j) = '0';
                    
                }
                idx += len + 8 - (len % 8);
            }
            else
            {
                idx += len;
            }
        }
        for(i = 0; i < idx; i++)
        {
            printf("%c", buf_p[i]);
            if((i + 1)% 8 == 0)
            {
                printf("\n");
            }
        }
        
        return 0;
    }
    

    ==================================>5

    题目描述
    写出一个程序,接受一个十六进制的数,输出该数值的十进制表示。
    输入描述:
    输入一个十六进制的数值字符串。注意:一个用例会同时有多组输入数据,请参考帖子https://www.nowcoder.com/discuss/276处理多组输入的问题。
    输出描述:
    输出该数值的十进制字符串。不同组的测试用例用\n隔开

    #include <stdio.h>
    #include <string.h>
    int mapChar(char ch)
    {
        if(ch >= '0' && ch <= '9')
        {
            return (ch - '0');
        }
        else if(ch >= 'a' && ch <= 'f')
        {
            return (ch - 'a' + 10);
        }
        else if(ch >= 'A' && ch <= 'F')
        {
            return (ch - 'A' + 10);
        }
        else
        {
            return -1;
        }
    }
    int isHexNum(char *p, int n)
    {
        int i;
        if(p == NULL)
        {
            printf("isHexNum:input error!\n");
            return -2;
        }
        if(p[0] != '0')
        {
            return -1;
        }
        if(p[1] != 'x' && p[1] != 'X')
        {
            return -1;
        }
        for(i = 2; i < n; i++)
        {
            if( !((p[i] >= '0' && p[i] <= '9') || 
                (p[i] >= 'a' && p[i] <= 'f') || 
                (p[i] >= 'A' && p[i] <= 'F') ||
                p[i] == ' '))
            {
                return -1;          
            }
        }   
        return 0;
    }
    int jizhi(char *p, int n)
    {
        int i;
        int ret;
        int len;
        len = 0;
        for(i = 2; i < n; i++)
        {
            if(p[i] == ' ')break;
            len++;
        }
        ret = 0;
        for(i = 0; i < len ; i++)
        {
            
            if(mapChar(p[i + 2]) == -1)
            {
                return -1;
            }
            ret += mapChar(p[i +2]) << ((len - i - 1) * 4);
        }
        return ret;
    } 
    int main(void)
    {
        int num = 2;
        int i;
        char str[128] = {0};
        int ret[num];
        for(i = 0; i < num; i++)
        {
            gets(str);
            if(isHexNum(str, strlen(str)) == -1)
            {
                printf("main:input error:\n");
                continue;
            }
            ret[i] = jizhi(str, strlen(str));
            
        }
        for(i = 0; i < num; i++)
        {
             if(ret[i] == -1)
            {
                printf("error\n");
            }
            else
            {
                printf("%d\n", ret[i]);
            }   
        }   
        return 0;
    }
    

    ==================================>6

    题目描述

    功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如180的质因子为2 2 3 3 5 )
    最后一个数后面也要有空格

    输入描述:

    输入一个long型整数

    输出描述:

    按照从小到大的顺序输出它的所有质数的因子,以空格隔开。最后一个数后面也要有空格。

    #include <stdio.h>
    
    long int isPermeNum(long n)
    {
        int i;
        int judge = n;
        for(i = 2; judge > 1 && i < judge; i++)
        {
            if(n % i == 0)
            {
                return i;//返回最小的质因数(注:1不是质因数)
            }   
            judge = n / i + 1;
        }
        return 0;
    }
    int getSubPrimeNum(long int num, long int *p)
    {
        long ret;
        ret = isPermeNum(num);
        if(ret >= 2)
        {
            *p = ret;   
            getSubPrimeNum(num / ret, p + 1);
            
        }
        else
        {
            *p = num;
            return 0;
        }
        return 0;
    }
    int main(void)
    {
        int i;
        long int num;
        long int member[128] = {0};
        int n;
        scanf("%d", &num);
        getSubPrimeNum(num, member);
        for(i = 0; i < 10;i++)
        {
            if(member[i] < 2 || member[i] >= num)break;
            printf("%d ", member[i]);
        }
    }
    

    ==================================>7

    题目描述

    写出一个程序,接受一个正浮点数值,输出该数值的近似整数值。如果小数点后数值大于等于5,向上取整;小于5,则向下取整。
    输入描述:

    输入一个正浮点数值

    输出描述:

    输出该数值的近似整数值

    #include <stdio.h>
    
    int toInter(float f)
    {
        int a = (int)f;
        if(f - (float)a >= 0.5)
        {
            a += 1;
        }
        return a;
    }
    int main(void)
    {
        float f;
        scanf("%f", &f);
        printf("%d", toInter(f));
        return 0;
    }
    

    ==================================>8

    题目描述

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

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

    输出描述:

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

    #include <stdio.h>
    #define MAX_NUM 64
    typedef struct Record{
        int key;
        int value;
    }Record_t;
    typedef struct Table{
        int num;
        Record_t data[MAX_NUM];
    }Table_t;
    void showTable(Table_t t)
    {
        int i; 
        for(i = 0; i < t.num; i ++)
        {
            printf("%d ", t.data[i].key);
            printf("%d\n", t.data[i].value);
        }
    }
    void tablePro(Table_t *t)
    {
        //选择排序法
        int i, j, k;
        Table_t buf;
        buf.num = 0;
        buf.data[0].key = t->data[0].key;
        buf.data[0].value = t->data[0].value;
        int cnt;
        cnt = 1;
        Record_t r_tmp, r_tmp2;
        for(i = 1; i < t->num; i++)
        {
            for(j = 0; j < cnt; j++)
            {
                if(t->data[i].key < buf.data[j].key)
                {
                    r_tmp = buf.data[j];
                    buf.data[j] = t->data[i];
                    for(k = 0; k <= cnt - j ; k++)//插入
                    {
                        r_tmp2 = buf.data[j + k + 1]; 
                        buf.data[j + k + 1] = r_tmp;
                        r_tmp = r_tmp2;
                    }
                    cnt++;
                    break;
                }
                else if(t->data[i].key == buf.data[j].key)
                {
                    buf.data[j].value += t->data[i].value;
                    break;
                    
                }
                else if(j == cnt - 1)
                {
                    buf.data[cnt] = t->data[i];
                    cnt ++;
                    break;
                }
                else
                {
                    ;
                }   
            }
        }
        buf.num = cnt;
        *t = buf;
    }
    
    int main(void)
    {
        Table_t t;
        int record_num = 4;
        int i;
        scanf("%d", &(t.num));
        for(i = 0; i < record_num; i ++)
        {
            scanf("%d", &(t.data[i].key));
            scanf("%d", &(t.data[i].value));    
        }
        tablePro(&t);
        showTable(t);
        return 0;
    }
    

    ==================================>9

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

    输入一个int型整数

    输出描述:

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

    #include <stdio.h>
    int mypow(int x, int n)
    {
        int i;
        int ret = 1;
        for(i = 0; i < n; i++)
        {
            ret *= x;
        }
        return ret;
    }
    int numPro(int num, int *array_p, int *n_p)
    {
        if(num % 10 == 0)
        {
            return -1;
        }
        int i, j;
        int a;
        int cnt;
        cnt = 1;    
        *array_p = num % 10;
        for(i = 2; mypow(10, i - 1) < num; i++)
        {
            a = (num % mypow(10, i)) / mypow(10, i - 1);
            //printf("a:%d   %d  i:%d  cnt:%d\n", a, mypow(10, i), i, cnt);
            for(j = 0; j < cnt; j++)
            {
                if(*(array_p + j) == a)
                {
                    break;
                }
                else if(j == cnt - 1)
                {
                    array_p[cnt] = a;
                    cnt++;
                    break;
                }
            }
        }
        *n_p = cnt;
        return 0;
    }
    int main(void)
    {
        int i;
        int num;
        scanf("%d", &num);
        int array[16] = {0};
        int cnt;    
        numPro(num, array, &cnt);
        for(i = 0; i < cnt; i++)
        {
            printf("%d", array[i]);
        }
        return 0;
    }
    

    ==================================>10

    题目描述
    编写一个函数,计算字符串中含有的不同字符的个数。字符在ACSII码范围内(0~127),换行表示结束符,不算在字符里。不在范围内的不作统计。多个相同的字符只计算一次
    例如,对于字符串abaca而言,有a、b、c三种不同的字符,因此输出3。
    输入描述:

    输入一行没有空格的字符串。

    输出描述:

    输出范围在(0~127)字符的个数。

    #include <stdio.h>
    int main(void)
    {
        char buf[1024];
        gets(buf);
        char str[1024] = {0};
        int cnt;
        int i, j;
        i = 0;
        cnt = 1;
        str[0] = buf[0];
        while(buf[i] != '\0')
        {
            if(buf[i] == '\n')
            {
                break;
            }
            else if(!(buf[i] >= 0 && buf[i] <= 127))
            {
                continue;
            }
            for(j = 0; j < cnt; j++)
            {
                if(buf[i] == str[j])
                {
                    break;
                }
                else if(j == cnt - 1)
                {
                    str[cnt] = buf[i];
                    cnt++;
                    break;
                }
            }
            i++;
        }
        if(!(buf[0] >= 0 && buf[0] <= 127))cnt--;
        printf("%d", cnt);
        return 0;
    }
    

    ==================================>11

    题目描述
    输入一个整数,将这个整数以字符串的形式逆序输出

    程序不考虑负数的情况,若数字含有0,则逆序形式也含有0,如输入为100,则输出为001

    输入描述:

    输入一个int整数

    输出描述:

    将这个整数以字符串的形式逆序输出

    #include <stdio.h>
    #include <string.h>
    int main(void)
    {
        char buf[32] = {0};
        int num;
        int len;
        int i;
        scanf("%d", &num);
        sprintf(buf, "%d", num);    
        i = 0;
        len = strlen(buf);
        while(buf[i] != '\0')
        {
            printf("%c", buf[len - i - 1]); 
            i++;
        }
        return 0;
    }
    

    ==================================>12

    题目描述

    接受一个只包含小写字母的字符串,然后输出该字符串反转后的字符串。(字符串长度不超过1000)
    输入描述:

    输入一行,为一个只包含小写字母的字符串。

    输出描述:

    输出该字符串反转后的字符串。

    #include <stdio.h>
    #include <string.h>
    int main(void)
    {
        char buf[1024] = {0};
        gets(buf);
        int len = strlen(buf);
        int i;
        for(i = 0; i < len; i++)
        {
            printf("%c", buf[len - i - 1]);
        }
        
        return 0;
    }
    

    ==================================>13

    题目描述

    将一个英文语句以单词为单位逆序排放。例如“I am a boy”,逆序排放后为“boy a am I”
    所有单词之间用一个空格隔开,语句中除了英文字母外,不再包含其他字符
    输入描述:

    输入一个英文语句,每个单词用空格隔开。保证输入只包含空格和字母。

    输出描述:

    得到逆序的句子

    #include <stdio.h>
    #include <string.h>
    int main(void)
    {
        char str[256] = {0};
        gets(str);
        char buf[64][16] = {{0},};
        int idx_a, idx_b;
        int i;
        int cnt;
        i = 0;
        idx_a = idx_b = 0;
        while(str[i] != '\0')
        {
            if(str[i] == ' ')
            {
                if(i > 0 && str[i - 1] != ' ')
                {
                    buf[idx_a][idx_b] = '\0';
                    idx_a++;    
                    idx_b = 0;
                }
                i++;
                continue;
            }
            buf[idx_a][idx_b] = str[i];
            idx_b++;
            i++;
        }
        if(str[strlen(str) - 1] != ' ')
        {
            cnt = idx_a + 1;
        }
        else
        {
            cnt = idx_a;
        }
        for(i = 0; i < cnt; i ++)
        {
            printf("%s ", buf[cnt - i - 1]);
        }
        
        return 0;
    }
    

    ==================================>14

    题目描述
    给定n个字符串,请对n个字符串按照字典序排列。
    输入描述:

    输入第一行为一个正整数n(1≤n≤1000),下面n行为n个字符串(字符串长度≤100),字符串中只含有大小写字母。

    输出描述:

    数据输出n行,输出结果为按照字典序排列的字符串。

    #include <stdio.h>
    #include <string.h>
    
    void toLower(char *p, int max)
    {
        int i;
        i = 0;
        while(p[i] != '\0')
        {
            if(p[i] >= 'A' && p[i] <= 'Z')
            {
                p[i] -= 'A' - 'a';
            }
            i++;
            if(i > max)break;
        }
    }
    
    int main(void)
    {
        int num;
        scanf("%d", &num);
        int i, j;
        char buf[512][16] = {{0},};
        char str_tmp[16] = {0};
        getchar();//接收换行符
        for(i = 0; i < num; i++)
        {
            gets(str_tmp);
            toLower(str_tmp, 16 - 1);
            strcpy(buf[i],/* strlwrtolower*/(str_tmp));
        }
        
        for(i = num - 1; i > 0; i --)
        {
            for(j = 0; j < i; j ++)
            {
                if(strcmp(buf[j], buf[j + 1]) > 0)
                {
                    strcpy(str_tmp, buf[j]);
                    strcpy(buf[j], buf[j + 1]);
                    strcpy(buf[j + 1], str_tmp);                    
                }
            }
        }   
        for(i = 0; i < num; i ++)
        {
            printf("%s\n", buf[i]);
        }
        return 0;
    }
    
    

    ==================================>15

    题目描述

    输入一个int型的正整数,计算出该int型数据在内存中存储时1的个数。
    输入描述:

    输入一个整数(int类型)

    输出描述:

    这个数转换成2进制后,输出1的个数

    #include <stdio.h>
    
    int main(void)
    {
        int num;
        scanf("%d", &num);
        
        int i;
        int tmp;
        int cnt ;
        cnt = 0;
        tmp = 0;
        for(i = 0;tmp < num; i++)
        {
            tmp = (int)((int)1 << i);
            if((tmp & num) > 0)cnt++;
        }
        printf("%d", cnt);
        return 0;
    }
    
    

    ==================================>16

    题目描述

    请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。

    所有的IP地址划分为 A,B,C,D,E五类

    A类地址1.0.0.0~126.255.255.255;

    B类地址128.0.0.0~191.255.255.255;

    C类地址192.0.0.0~223.255.255.255;

    D类地址224.0.0.0~239.255.255.255;

    E类地址240.0.0.0~255.255.255.255

    私网IP范围是:

    10.0.0.0~10.255.255.255

    172.16.0.0~172.31.255.255

    192.168.0.0~192.168.255.255

    子网掩码为二进制下前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码)
    注意二进制下全是1或者全是0均为非法

    注意:
    1. 类似于【0...】和【127...】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时可以忽略
    2. 私有IP地址和A,B,C,D,E类地址是不冲突的

    输入描述:

    多行字符串。每行一个IP地址和掩码,用~隔开。

    输出描述:

    统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。
    示例1

    输入

    [复制](javascript:void(0);)

    <pre>10.70.44.68~255.254.255.0
    1.0.0.1~255.0.0.0
    192.168.0.2~255.255.255.0
    19..0.~255.255.255.0
    </pre>

    输出

    [复制](javascript:void(0);)

    <pre>1 0 1 0 0 2 1
    </pre>

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    int strCut(char *from, char *to, int start, int end)
    {
        int len = strlen(from);
        int i;
        int cnt;
        cnt = 0;
        for(i = 0; i < len; i ++)
        {
            if(i >= start && i <= end)
            {
                to[cnt] = from[i] ;
                cnt++;
            }
            else if(i > end)
            {   
                break;
            }
        }
        to[cnt] = '\0';
        return 0;
    }
    int getCharPos(char *str, char ch, int *pos, int *cnt)
    {
        int len = strlen(str);
        int i;
        int cnt_tmp;
        cnt_tmp = 0;
        for(i = 0; i < len; i ++)
        {
            if(ch == str[i])
            {     
                pos[cnt_tmp] = i;
                cnt_tmp++;     
            }
        }
        *cnt = cnt_tmp;
        return 0;
    }
    int isIpaddr(char *str, int *ip)
    {
        int pos[16] = {0};//有溢出风险
        int cnt;
        int i;
        char ip_array[8][4] = {{0},};
        int len = strlen(str);
        int ip_tmp;
        int tmp;
        getCharPos(str, '.', pos, &cnt);
        if(cnt != 3)
        {
            return -1;
        }
        for(i = 0; i < 2; i++)
        {
            if(pos[i] >= pos[i+1])
            {
                return -2;
            }
        }   
        for(i = 0; i < 4; i++)
        {
            if(i == 0)
            {
                strCut(str, ip_array[i], 0, pos[i] - 1);        
            }
            else if(i == 3)
            {
                strCut(str, ip_array[i], pos[i - 1] + 1, len - 1);
            }
            else
            {
                strCut(str, ip_array[i], pos[i - 1] + 1, pos[i] - 1);    
            }  
        }
        ip_tmp = 0;
        for(i = 0; i < 4; i++)
        {
            tmp = atoi(ip_array[i]);
            if(tmp == 0 && ip_array[i][0] != '0') 
            {       
                return -3;
            }
            if(!(tmp >= 0 && tmp <= 255))
             {
                 return -4;  
             }
            ip_tmp += tmp << ( (3 - i) * 8);
        }
        *ip = ip_tmp;
        return 0;
    }
    int isMaskOk(char *mask)
    {
        int value;
        if(isIpaddr(mask, &value) != 0)return -1;
        int num = sizeof(int);
        int i, j;
        for(i = 0; i < num * 8 - 1; i ++)
        {
            if((value & (int)1 << (num * 8 - i - 1)) == 0)
            {
                for(j = i + 1;j < num * 8; j++)
                {
                    if((value & (int)1 << (num * 8 - j - 1)) != 0)
                    {
                        return -1;
                    }
                }
                break;
            }
        }
        return 0;
    }
    int linePro(char *str, char *ip_out, char *mask_out)
    {
        int pos[16] = {0};
        int cnt = 0;
        getCharPos(str, '~', pos, &cnt);
        if(cnt < 1)
        {
            return -1;
        }
        int len = strlen(str);
        strCut(str, ip_out, 0, pos[0] - 1);
        strCut(str, mask_out, pos[0] + 1, len - 1);
        return 0;   
    }
    int ipType(int ip, int *type, int *is_pri)
    {
        const int start[] = 
        {
            1 << 24,
            128 << 24,
            192 << 24,
            224 << 24,
            240 << 24,
            //私有地址
            10 << 24,
            172 << 24 | 16 << 16,
            192 << 24 | 168 << 16
        };
        const int end[] = 
        {
            126 << 24 | 255 << 16 | 255 << 8 |255,
            191 << 24 | 255 << 16 | 255 << 8 |255,
            223 << 24 | 255 << 16 | 255 << 8 |255,
            239 << 24 | 255 << 16 | 255 << 8 |255,
            255 << 24 | 255 << 16 | 255 << 8 |255,
            //私有地址
            10  << 24 | 255 << 16 | 255 << 8 |255,
            172 << 24 | 31 << 16 | 255 << 8 | 255 ,
            192 << 24 | 168 << 16 | 255 << 8 | 255 
        };
        int i;
        *type = 0, *is_pri = 0;
        for(i = 0; i < 5;  i++)
        {
            if(ip >= start[i] && ip <= end[i])
            {
                *type = i + 1;
                break;      
            }
        }
        for(i = 5; i < 8;  i++)
        {
            if(ip >= start[i] && ip <= end[i])
            {
                *is_pri = 1;
                break;      
            }
        }
        return 0;
    }
    int main(void)
    {
        int num = 4;
        char str[8][128] = {{0},};
        int i;
        char ip_str[64] = {0};
        char mask_str[64] = {0};
        int a, b, c, d, e, error, pri;
        int ip_value;
        int ret;
        
        for(i = 0; i < num; i++)
        {
             gets(str[i]);
        }
        a = b = c = d = e = error = pri = 0;
        int type, is_pri;
        for(i = 0; i < num; i++)
        {
            memset(ip_str, sizeof(ip_str), 0);
            memset(mask_str, sizeof(ip_str), 0);
            linePro(str[i], ip_str, mask_str);
            if(isMaskOk(mask_str) != 0)
            {
                error++;
                continue;
            }   
            ret = isIpaddr(ip_str, &ip_value);
            if(ret == 0)
            {
                ipType(ip_value, &type, &is_pri);
                if(type == 1)a++;
                else if(type == 2)b++;
                else if(type == 3)c++;
                else if(type == 4)d++;
                else if(type == 5)e++;
                if(is_pri == 1)pri++;
            }
            else
            {
                error++;
            }
        }
        printf("%d %d %d %d %d %d %d\n", a, b, c, d, e, error, pri);
        return 0;
    }
            
    

    ==================================>17

    题目描述

    计算最少出列多少位同学,使得剩下的同学排成合唱队形

    说明:

    N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。
    合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足存在i(1<=i<=K)使得T1<T2<......<Ti-1<Ti>Ti+1>......>TK。
    你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

    注意不允许改变队列元素的先后顺序
    请注意处理多组输入输出!

    输入描述:

    整数N

    输出描述:

    最少需要几位同学出列

    示例1
    输入
    复制

    8
    186 186 150 200 160 130 197 200

    输出
    复制

    4

    #include <stdio.h>
    int queueIsOk(unsigned int *array, int n)
    {
        int i, j;
        for(i = 0; i < n - 1; i++)
        {
            if(!(array[i] < array[i + 1]))
            {
                for(j = i + 1; j < n - 1; j++)
                {
                    if(!(array[j] > array[j + 1]))
                    {
                        return -1;
                    }
                }
            }     
        }
        return 0; 
    }
    int queuePro(unsigned int *array, int n)
    {
        //限制:队列大小不超过32位(一个整形的二进制位数)
        if(n > 32)return -1;
        int i, j;
        int totle;
        int cnt;
        int out_peple_num;
        totle = 1 << n;
        unsigned int array_tmp[32];
        out_peple_num = n;
        for(i = 0; i < totle; i++)
        {
            cnt = 0;
            for(j = 0; j < n; j ++)
            {
                if(((i & (1 << j)) != 0))
                {
                     array_tmp[cnt] = array[j];  
                    cnt++;
                }    
            }
            if(cnt > 0)
            {
                if(queueIsOk(array_tmp, cnt) == 0 && out_peple_num > (8 - cnt))
                {
                    /*printf("====>0x%8x  cnt:%d  ", i, cnt);
                    for(j = 0; j < cnt; j++)
                    {
                        printf("%d\t", array_tmp[j]);
                    }
                    printf("\n");*/
                    out_peple_num = 8 - cnt;   
                }
            }   
        }
        return out_peple_num;
    }
    int main(void)
    {
        //unsigned int num[] = {186, 186, 150, 200, 160, 130, 197, 200 };
        unsigned int num[32];
        int n;
        int i;
        scanf("%d", &n);
        if(n > 32)
        {
            printf("n is bigger than 32\n");
        }
        for(i = 0; i < n; i++)
        {
            scanf("%d", &num[i]);
        }
        printf("%d", queuePro(num, 8));
        return 0;
    }
    
    

    ==================================>18

    ==================================>19

    ==================================>20

    ==================================>21

    ==================================>22

    ==================================>23

    相关文章

      网友评论

          本文标题:008-牛客机试题

          本文链接:https://www.haomeiwen.com/subject/apxghltx.html