008-牛客机试题

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

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

题目

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

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

C语言

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

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 

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

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

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 

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

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 

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);)

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

输出

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

1 0 1 0 0 2 1

#include 
#include 
#include 
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)使得T1Ti+1>......>TK。
你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

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

输入描述:

整数N

输出描述:

最少需要几位同学出列

示例1
输入
复制

8
186 186 150 200 160 130 197 200

输出
复制

4

#include 
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-牛客机试题)