华为机试 108 题(C 语言解答)

Nowcoder题库链接:华为机试

  • HJ1 字符串最后一个单词的长度(字符串)

华为机试 108 题(C 语言解答)_第1张图片

输入:hello nowcoder

输出:8

说明:
最后一个单词为nowcoder,长度为8  

示例代码: HJ1.c


#include 
#include 
#include 
#define LEN 5001

char * s_gets(char * st, int n);
int get_length(char * st);         // 获取字符串最后一个单词长度

int main(void)
{
    char str[LEN];
    
    if (s_gets(str, LEN) != NULL && *str != '\0')
        printf("%d", get_length(str));
        
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

int get_length(char * st)
{
    int count = 0;
    
    while (*st)
    {
        if (isspace(*st))
            count = 0;
        else
            count++;
        st++;
    }
    
    return count;
}

  • HJ2 计算某字符出现次数(字符串)

华为机试 108 题(C 语言解答)_第2张图片

输入:ABCabc
     A

输出:2

示例代码:HJ2.c


#include 
#include 
#include 
#define LEN 1001

char * s_gets(char * st, int n);
int appear(char * st, int ch);

int main(void)
{
    char str[LEN];
    char ch;
    
    if (s_gets(str, LEN) != NULL && *str != '\0')
    {
        scanf("%c", &ch);
        printf("%d", appear(str, ch));
    }
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

int appear(char * st, int ch)
{
    int count = 0;
    int s;
    
    if (isupper(ch))
        s = tolower(ch);
    else
        s = toupper(ch);
    while (*st)
    {
        if (*st == s || *st == ch)
            count++;
        st++;
    }
    
    return count;
}

  • HJ3 明明的随机数(基础数学)

华为机试 108 题(C 语言解答)_第3张图片

输入:
3
2
2
1

输出:
1
2

说明:输入解释:
第一个数字是3,也即这个小样例的N=3,说明用计算机生成了3个1到500之间的随机整数,接下来每行一个随机数字,共3行,也即这3个随机数字为:
2
2
1
所以样例的输出为:
1
2       

示例代码:HJ3.c


#include 
#define LEN 501

int main(void)
{
    int n;
    int i;
    static int mark[LEN];
    int num;
    
    while (scanf("%d", &n) == 1)
    {
        for (i = 0; i < n; i++)
        {
            scanf("%d", &num);
            mark[num] = 1;
        }
        for (i = 1; i < LEN; i++)
        {
            if (mark[i])
                printf("%d\n", i);
        }
        for (i = 1; i < LEN; i++)
            mark[i] = 0;
    }
    
    return 0;
} 

  • HJ4 字符串分隔(字符串)

华为机试 108 题(C 语言解答)_第4张图片

输入:abc

输出:abc00000

示例代码:HJ4.c


#include 
#include 
#define LEN 101
#define SIZE 8

char * s_gets(char * st, int n);
void get_det(char * st);

int main(void)
{
    char str[LEN];
    
    if (s_gets(str, LEN) != NULL && *str != '\0')
        get_det(str);
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

void get_det(char * st)
{
    while (*st)
    {
        int i;
        
        if ((int) strlen(st) < SIZE)
        {
            printf("%s", st);
            for (i = 0; i < SIZE - (int) strlen(st); i++)
                putchar('0');
            putchar('\n');
            break;
        }
        for (i = 0; i < SIZE; i++, st++)
            putchar(*st);
        putchar('\n');
    }
}

  • HJ5 进制转换(字符串)

华为机试 108 题(C 语言解答)_第5张图片

输入:0xAA

输出:170

示例代码:HJ5.c


#include 
#include 
#include 
#define LEN 21

char * s_gets(char * st, int n);
void get_dec(char * st);

int main(void)
{
    char str[LEN];
    
    while (s_gets(str, LEN) != NULL && *str != '\0')
        get_dec(str);
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

void get_dec(char * st)
{
    int i;
    int num = 0;
    char str[LEN];
    int temp;
    
    for (i = 2; i < (int) strlen(st); i++)
    {
        if (isdigit(st[i]))
            temp = st[i] - '0';
        else
            temp = st[i] - 'A' + 10;
        num = num * 16 + temp;
    }
    sprintf(str, "%d", num);
    puts(str);
}

  • HJ6 质数因子(基础数学)

华为机试 108 题(C 语言解答)_第6张图片

输入:180

输出:2 2 3 3 5

示例代码:HJ6.c


#include 

void get_div(long n);

int main(void)
{
    long int num;
    
    scanf("%ld", &num);
    get_div(num);
    
    return 0;
}

void get_div(long n)
{
    int i;
    
    for (i = 2; i * i <= n; i++)
    {
        while (n % i == 0)
        {
            printf("%d ", i);
            n /= i;
        }
    }
    if (n - 1) // 说明只能被本身整除,又由于 1 不是质数,故需要大于 1 
        printf("%ld\n", n);
}

  • HJ7 取近似值(基础数学)

华为机试 108 题(C 语言解答)_第7张图片

输入:5.5

输出:6

说明:
0.5>=0.5,所以5.5需要向上取整为6

示例代码:HJ7.c


#include 

int main(void)
{
    double num;
    
    scanf("%lf", &num);
    printf("%d", (int) (num + 0.5));
    
    return 0;
}

  • HJ8 合并表记录(结构体)

华为机试 108 题(C 语言解答)_第8张图片

输入:
4
0 1
0 2
1 2
3 4

输出:
0 3
1 2
3 4

示例代码:HJ8.c


#include 
#include 
#include 

typedef struct list {
    int x;
    int y;
    bool marked;
} List; 

void get_item(List * pl, int n);
void com_item(List * pl, int n);
void show_item(List * pl, int n);
void order_item(List * pl, int n);

int main(void)
{
    int n;
    List * pl;
    
    scanf("%d", &n);
    pl = (List *) malloc(n * sizeof(List));
    get_item(pl, n);
    com_item(pl, n);
    order_item(pl, n);
    show_item(pl, n);
    free(pl);
    
    return 0;
}

void get_item(List * pl, int n)
{
    int i;
    
    for (i = 0; i < n; i++)
    {
        scanf("%d%d", &(pl + i)->x, &(pl + i)->y);
        (pl + i)->marked = false;
    }
}

void com_item(List * pl, int n)
{
    int i, j;
    
    for (i = 0; i < n - 1; i++)
    {
        for (j = i + 1; j < n; j++)
        {
            if ((pl + i)->marked == true)
                break;
            if ((pl + i)->x == (pl + j)->x && (pl + j)->marked == false)
            {
                (pl + i)->y += (pl + j)->y;
                (pl + j)->marked = true;
            }
        }
    }         
}

void show_item(List * pl, int n)
{
    int i;
    
    for (i = 0; i < n; i++)
    {
        if ((pl + i)->marked == false)
            printf("%d %d\n", (pl + i)->x, (pl + i)->y);    
    }    
}

void order_item(List * pl, int n)
{
    int i, j;
    int temp;
    
    for (i = 0; i < n - 1; i++)
    {
        for (j = i + 1; j < n; j++)
        {
            if ((pl + i)->x > (pl + j)->x && (pl + j)->marked == false && (pl + i)->marked == false)
            {
                temp = (pl + i)->x;
                (pl + i)->x = (pl + j)->x;
                (pl + j)->x = temp;
                temp = (pl + i)->y;
                (pl + i)->y = (pl + j)->y;
                (pl + j)->y = temp;
            }
        }    
    }            
}

  • HJ9 提取不重复的整数(字符串)

华为机试 108 题(C 语言解答)_第9张图片

输入:9876673

输出:37689

示例代码:HJ9.c


#include 
#include 
#define LEN 100

int no_repeat(int n);

int main(void)
{
    int num;
    
    scanf("%d", &num);
    printf("%d", no_repeat(num));
    
    return 0;
}

int no_repeat(int n)
{
    static char str[LEN], str2[LEN];
    int i, j;
    int number = 0, count = 0;
    int flag;
    
    sprintf(str, "%d", n);
    for (i = (int) strlen(str) - 1; i > -1; i--)
    {
        flag = 0;
        for (j = 0; j < (int) strlen(str2); j++)
        {
            if (*(str + i) == *(str2 + j))
            {
                flag = 1;
                break;
            }    
        }    
        if (!flag)
        {
            *(str2 + strlen(str2)) = *(str + i);
            count++;
        }
    }
    for (i = 0; i < count; i++)
        number = number * 10 + str2[i] - '0';
        
    return number;
}

  • HJ10 字符个数统计(字符串)

华为机试 108 题(C 语言解答)_第10张图片

输入:abc

输出:3

示例代码:HJ10.c


#include 
#include 
#define LEN 1001
#define TYPE 128

char * s_gets(char * st, int n);
int get_count(char * st);

int main(void)
{
    char str[LEN];
    
    if (s_gets(str, LEN) != NULL && *str != '\0')
        printf("%d", get_count(str));
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

int get_count(char * st)
{
    int count = 0;
    static int ascii[TYPE];
    int i;
    int flag;
    
    while (*st)
    {
        flag = 0;
        for (i = 0; i < count; i++)
        {
            if (*st == ascii[i])
            {
                st++;
                flag = 1;
                break;
            }        
        }
        if (flag == 0)
            ascii[count++] = *st;
    }
    
    return count;
}

  • HJ11 数字颠倒(字符串)

华为机试 108 题(C 语言解答)_第11张图片

输入:1516000

输出:0006151

示例代码:HJ11.c


#include 
#include    // 提供 strlen() 函数原型 
#define LEN 20

int main(void)
{
    int num;          // 待输入的数字 
    char str[LEN];    // 保存转换后的字符串 
    int i;
    
    scanf("%d", &num);
    sprintf(str, "%d", num);
    for (i = strlen(str) - 1; i > -1; i--)
        putchar(*(str + i));
    
    return 0;
} 

  • HJ12 字符串反转(字符串)

华为机试 108 题(C 语言解答)_第12张图片

输入:abcd

输出:dcba

示例代码:HJ12.c


#include 
#include             // 提供 strlen()、strchr() 函数 
#define LEN 1001               // 最多1000个字符包括1001个字符,多余一个给空字符 

char * s_gets(char *, int n);  // 获取最多 n - 1 个字符串 

int main(void)
{
    char str[LEN];
    int i;
    
    if (s_gets(str, LEN) != NULL && *str != '\0')
    {
        for (i = strlen(str) - 1; i >= 0 ; i--)
            putchar(*(str + i));
    }
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

  • HJ13 句子逆序(字符串)

华为机试 108 题(C 语言解答)_第13张图片

输入:I am a boy

输出:boy a am I

示例代码:HJ13.c


#include 
#include 
#define LEN 1001

char * s_gets(char * st, int n);
void reverse(char * st);

int main(void)
{
    char str[LEN];
    
    if (s_gets(str, LEN) != NULL && *str != '\0')
        reverse(str);
        
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

void reverse(char * st)
{
    int i;
    
    for (i = (int) strlen(st) - 1; i > -1; i--)
        if (*(st + i) == ' ')
        {
            printf("%s ", st + i + 1);
            *(st + i) = '\0';
        }
        else if (i == 0)
            puts(st);
}

  • HJ14 字符串排序(字符串)

华为机试 108 题(C 语言解答)_第14张图片

输入:
9
cap
to
cat
card
two
too
up
boat
boot

输出:
boat
boot
cap
card
cat
to
too
two
up

示例代码:HJ14.c


#include 
#include 
#include 
#define LEN 101

void order_str(char **, int n);

int main(void)
{
    int n;
    int i;
    char temp[LEN];
    
    scanf("%d", &n);
    char * str[n];
    for (i = 0; i < n; i++)
    {    
        scanf("%s", temp);
        str[i] = (char *) malloc(((int) strlen(temp) + 1) * sizeof(char));
        strcpy(str[i], temp);
    }
    order_str(str, n);
    for (i = 0; i < n; i++) // 怎么申请,怎么释放 
        free(str[i]);
    
    return 0;
}

void order_str(char ** str, int n)
{
    int i, j;
    char * temp;
    
    for (i = 0; i < n - 1; i++)
    {
        for (j = i + 1; j < n; j++)
        {
            if (strcmp(str[i], str[j]) > 0)
            {
                temp = str[i];
                str[i] = str[j];
                str[j] = temp;
            }
        }    
    }        
    for (i = 0; i < n; i++)
        puts(str[i]);
}

  • HJ15 求int型正整数在内存中存储时1的个数(位操作)

华为机试 108 题(C 语言解答)_第15张图片

输入:5

输出:2

示例代码:HJ15.c


#include 

int main(void)
{
    int count = 0;
    int num;
    
    scanf("%d", &num);
    while (num)
    {
        count += (num & 1);
        num >>= 1;    
    }
    printf("%d", count);
    
    return 0;
}

  • HJ16 购物单(动态规划,背包问题)

华为机试 108 题(C 语言解答)_第16张图片
华为机试 108 题(C 语言解答)_第17张图片

输入:
50 5
20 3 5
20 3 5
10 3 0
10 2 0
10 1 0

输出:
130

说明:
由第 1 行可知总钱数 N 为 50 以及希望购买的物品个数 m 为 5;
第 2 和第 3 行的 q 为 5,说明它们都是编号为 5 的物品的附件;
第 4 ~ 6 行的 q 都为 0,说明它们都是主件,它们的编号依次为 3 ~ 5;
所以物品的价格与重要度乘积的总和的最大值为 10 * 1 + 20 * 3 + 20 * 3 = 130    

示例代码:HJ16.c


#include 
#include 
#define N 60                               // 最多 60 件物品
#define M 32000                            // 最多预算数 
#define MAX(a, b) ((a) > (b)) ? (a) : (b)  // 宏函数参数最好加括号避免出错 

int main(void)
{
    int money;               // 预算
    int n;                   // 货物数量
    int v;                   // 单个物品价格
    int p;                   // 单个物品满意度
    int q;                   // 物品所属编号
    static int price[N][4];  // 存储可能的四种组合的商品的价格,静态变量自动初始化为 0 
    static int weight[N][4]; // 存储可能出现的四种组合的满意度 
    int merge_price[N][4];   // 存储合并后的价格
    int merge_weight[N][4];  // 存储合并后的满意度 
    int count = 0;           // 记录组合商品数量 
    static int dp[N][M];     // M 数量的金钱在购买前 N 个已经出现物品中采取的所有方案中所能最多获取的满意度
    int max = 0;             // 存储最大满意度 
    int i, j, k; 
        
    while (scanf("%d%d", &money, &n) == 2)
    {
        /* 数据处理开始,录入并合并数据*/ 
        for (i = 0; i < n; i++)
        {
            scanf("%d%d%d", &v, &p, &q);
            if (0 == q)
            {
                price[i][0] = v;
                weight[i][0] = v * p;
            }
            else if (0 == price[q - 1][1]) // 表明是数组编号为 q - 1第 1 件附件 
            {
                price[q - 1][1] = v;
                weight[q - 1][1] = v * p; 
            }
            else                           // 表明是数组编号为 q - 1的物品的第 2 件附件
            {
                price[q - 1][2] = v;
                weight[q - 1][2] = v * p;  
                price[q - 1][3] = price[q - 1][1] + v;
                weight[q - 1][3] = weight[q - 1][1] + v * p; 
            }
        }
        // 合并可能出现的商品的价格和满意度
        for (i = 0; i < n; i++)
        {
            if (price[i][0])                  // 该商品是主件 
            {
                for (j = 1; j < 4; j++)       // 只能购买包含主件的商品,合并可能购买的商品价格 
                {
                    price[i][j] += price[i][0];
                    weight[i][j] += weight[i][0]; 
                }
                for (j = 0; j < 4; j++)       // 剔除为 0 的数据 
                {
                    merge_price[count][j] = price[i][j];
                    merge_weight[count][j] = weight[i][j];
                }
                count++;
            }    
        }
        /* 数据处理完成 ,动态规划开始 */ 
        for (i = 1; i <= count; i++)                // 对于 1 ~ count 件物品 
        {
            for (j = 10; j <= money; j += 10)
            {
                max = dp[i - 1][j];                // 数量 j 的金钱购买前 i - 1 件已经出现物品最多获得满意度
                /* 开始尝试购买才出现的第 i 件物品(数组下标为 i - 1) */ 
                for (k = 0; k < 4; k++)            // 购买必须包含主件的商品之一,取最大值 
                {
                    if (!merge_price[i - 1][k])    // 不存在该组合
                        break; 
                    if (j - merge_price[i - 1][k] >= 0) // 如果买得起某个组合,比较这笔钱 没花之前的所能购买到的最大满意度加上购买该组合新增的满意度之和 和 不购买该组合之前所得满意度的大小 
                        max = MAX(max, dp[i - 1][j - merge_price[i - 1][k]] + merge_weight[i - 1][k]); // dp[i - 1] 指的是已经出现的前 i - 1 个物品的最大满意度,不是第 i 个,回退时金钱和商品编号都要减 
                }
                dp[i][j] = max;                    // 买不起或值会变小则不变,买得起且满意度增加则改变  
                /* 获得尝试购买后的最大满意度,尝试结束 */ 
            }    
        }
        printf("%d\n", dp[count][money]);
    }
    
    return 0;
}

  • HJ17 坐标移动(字符串)

华为机试 108 题(C 语言解答)_第18张图片

输入:A10;S20;W10;D30;X;A1A;B10A11;;A10;

输出:10,-10

示例代码:HJ17.c


#include 
#include 
#include 
#include 
#define LEN 10001

void get_cordinate(char * st);

int main(void)
{
    char str[LEN];
    
    while (scanf("%s", str) == 1)
        get_cordinate(str);
    
    return 0;
}

void get_cordinate(char * st)
{
    bool in_com = false;
    char str[4] = "WSAD";
    char order_1;
    int order_2 = 0;
    int x = 0, y = 0;
    char * st_b = st;
    
    while (*st)
    {
        if (strchr(str, *st) && in_com == false && (st == st_b || *(st - 1) == ';'))
        {
            order_1 = *st;
            in_com = true;
        }
        else if (in_com && isdigit(*st))
        {
            order_2 = order_2 * 10 + *st - '0';
        }
        else if (in_com && !isdigit(*st) && *st != ';')
        {
            in_com = false;
            order_2 = 0;
        }
        if (in_com && *st == ';')
        {
            switch (order_1)
            {
                case 'W':
                    y += order_2;
                    break;
                case 'S':
                    y -= order_2;
                    break;
                case 'A':
                    x -= order_2;
                    break;
                case 'D':
                    x += order_2;
                    break;
            }
            in_com = false;
            order_2 = 0;
        }
        st++; 
    }
    printf("%d,%d\n", x, y);
}

  • HJ18 识别有效的IP地址和掩码并进行分类统计(字符串)

华为机试 108 题(C 语言解答)_第19张图片

输入:
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

输出:
1 0 1 0 0 2 1

说明:
10.70.44.68~255.254.255.0的子网掩码非法,19..0.~255.255.255.0的IP地址非法,所以错误IP地址或错误掩码的计数为2;
1.0.0.1~255.0.0.0是无误的A类地址;
192.168.0.2~255.255.255.0是无误的C类地址且是私有IP;
所以最终的结果为1 0 1 0 0 2 1 

示例代码:HJ18.c


#include 
#include 
#include 
#include 
#include 
#define LEN 101

bool IsLegal_Ip(char * st);
bool IsLegal_Mask(char * st);

int main(void)
{
    char str[LEN];
    char * ip;
    char * mask;
    char * ip_1;
    char * ip_2;
    int ip1;
    int ip2;
    int a_count = 0;
    int b_count = 0;
    int c_count = 0;
    int d_count = 0;
    int e_count = 0;
    int w_count = 0;
    int p_count = 0;
    
    while (scanf("%s", str) == 1)
    {
        ip = strtok(str, "~");
        mask = strtok(NULL, "~");
        if (IsLegal_Mask(mask) && IsLegal_Ip(ip))
        {
            ip_1 = strtok(ip, ".");
            ip_2 = strtok(NULL, ".");
            ip1 = atoi(ip_1);
            ip2 = atoi(ip_2);
            if (!(ip1 == 0 || ip1 == 127))
            {
                if (ip1 > 0 && ip1 < 127)
                {
                    a_count++;
                    if (ip1 == 10)
                        p_count++;
                }
                if (ip1 > 127 && ip1 <= 191)
                {
                    b_count++;
                    if (ip1 == 172 && ip2 >= 16 && ip2 <= 31)
                        p_count++;
                }
                if (ip1 > 191 && ip1 <= 223)
                {
                    c_count++;
                    if (ip1 == 192 && ip2 == 168)
                        p_count++;
                }
                if (ip1 > 223 && ip1 <= 239)
                    d_count++;
                if (ip1 > 239 && ip1 <= 255)
                    e_count++;
            }    
        }
        else
        {
            ip_1 = strtok(ip, ".");
            ip1 = atoi(ip_1);
            if (ip1 != 127 && ip1 != 0)
                w_count++;
        }    
    }
    printf("%d %d %d %d %d %d %d", a_count, b_count, c_count, 
            d_count, e_count, w_count, p_count);
    
    return 0;
}

bool IsLegal_Ip(char * st)
{
    char * st_b = st;
    int num_count = 0;
    int dot_count = 0;
    int num = 0;
    
    while (*st)
    {
        if ((st == st_b  && !(*st >= '0' && *st <= '9')) 
            || (*st == '.' && !(*(st + 1) >= '0' && *(st + 1) <= '9')))
            return false;
        if (st == st_b && *st == '0' && isdigit(*(st + 1)))
            return false;
        if (*st == '.' && *(st + 1) == '0' && isdigit(*(st + 2)))
            return false;
        if (isdigit(*st))
        {
            num = 10 * num + *st - '0';
            if (!isdigit(*(st + 1)))
                num_count++;    
        }    
        if (*st == '.')
        {
            dot_count++;
            if (!(num >= 0 && num < 256))
                return false;    
            num = 0;
        }    
        st++;
    }
    if (!(num_count == 4 && dot_count == 3) || !(num >= 0 && num < 256))
        return false;
    
    return true;
}

bool IsLegal_Mask(char * st)
{
    char * mask_part;
    int num;
    int i, j;
    bool count_zero = false;
    int count_one = 0;
    int temp; 
    
    mask_part = strtok(st, ".");
    for (i = 0; i < 4; i++)
    {
        num = atoi(mask_part);
        if (num == 255)
            count_one++;
        if ((i == 0 && num == 0) || num < 0 || num > 255)
            return false;
        for (j = 0; j < 8; j++)
        {

            temp = (num >> (7 - j)) & 1;
            if (temp == 0)
                count_zero = true;
            if (temp == 1 && count_zero)
                return false;
        }
        if (i < 3)
            mask_part = strtok(NULL, ".");
    }
    if (count_one == 4)
        return false;
    
    return true;
}

  • HJ19 简单错误记录(字符串)

华为机试 108 题(C 语言解答)_第20张图片

输入:
D:\zwtymj\xccb\ljj\cqzlyaszjvlsjmkwoqijggmybr 645
E:\je\rzuwnjvnuz 633
C:\km\tgjwpb\gy\atl 637
F:\weioj\hadd\connsh\rwyfvzsopsuiqjnr 647
E:\ns\mfwj\wqkoki\eez 648
D:\cfmwafhhgeyawnool 649
E:\czt\opwip\osnll\c 637
G:\nt\f 633
F:\fop\ywzqaop 631
F:\yay\jc\ywzqaop 631
D:\zwtymj\xccb\ljj\cqzlyaszjvlsjmkwoqijggmybr 645

输出:
rzuwnjvnuz 633 1
atl 637 1
rwyfvzsopsuiqjnr 647 1
eez 648 1
fmwafhhgeyawnool 649 1
c 637 1
f 633 1
ywzqaop 631 2

说明:
由于D:\cfmwafhhgeyawnool 649的文件名长度超过了16个字符,达到了17,所以第一个字符'c'应该被忽略。
记录F:\fop\ywzqaop 631和F:\yay\jc\ywzqaop 631由于文件名和行号相同,因此被视为同一个错误记录,哪怕它们的路径是不同的。
由于循环记录时,只以第一次出现的顺序为准,后面重复的不会更新它的出现时间,仍以第一次为准,所以D:\zwtymj\xccb\ljj\cqzlyaszjvlsjmkwoqijggmybr 645不会被记录。  

示例代码HJ19.c


#include 
#include 
#include 
#include 
#include 
#define LEN 101

char * s_gets(char * st, int n);

int main(void)
{
    char temp[LEN];
    char ** pwrong;
    int count = 0;
    char * start;
    char * delima;
    char * pos;
    char ** record;
    static int record_num[8];
    static int record_line[8];
    int record_n = 0;
    bool appear = false, appear2 = false;
    int len;
    int len_num;
    int num;
    int i;
    
    if ((pwrong = (char **) malloc(sizeof(char *) * (LEN  - 1))) == NULL)
        puts("Wrong in memory allocation!");
    if ((record = (char **) malloc(sizeof(char *) * 8)) == NULL)
        puts("Wrong in memory allocation!");
    while (s_gets(temp, LEN) != NULL && *temp != '\0')
    {
        len_num = 0;
        pwrong[count] = (char *) malloc(sizeof(char) * ((int) sizeof(temp) + 1));
        strcpy(pwrong[count], temp);
        len = strlen(temp);
        delima = temp;
        while (strtok(delima, "\\") != NULL)
            delima = delima + (int) strlen(delima) + 1;
        for (i = len - 1; i > - 1; i--)
        {
            if (isdigit(temp[i]))
                len_num++;    
            if (temp[i] == '\0')
            {
                start = temp + i + 1;
                break;
            }
        }
        len = strlen(start);
        delima = strtok(start, " ");
        delima = strtok(NULL, " ");
        num = atoi(delima);
        if (len - len_num - 1 <= 16)
            start = pwrong[count] + i + 1;
        else
            start = pwrong[count] + i + 1 + len - len_num - 1 - 16;
        pos = pwrong[count] + i + 1;
        for (i = 0; i < count; i++)
        {
            if (strstr(pwrong[i], pos) != NULL)
            {
                appear = true;
                break;
            }
        }
        for (i = 0; i < record_n; i++)
        {
            if (strcmp(record[i], start) == 0 && record_line[i] == num)
            {
                appear2 = true;
                record_num[i]++;
                break;
            }
        }
        if (!appear && !appear2)
        {
            if (record_n < 8)
            {
                record_num[record_n] = 1;
                record_line[record_n] = num;
                record[record_n++] =start;
            }    
            else
            {
                for (i = 0; i < 7; i++)
                {
                    record[i] = record[i + 1];
                    record_num[i] = record_num[i + 1];
                    record_line[i] = record_line[i + 1];
                }    
                record[7] = start;
                record_num[7] = 1;
                record_line[7] = num;
            }
            
        }
        appear = appear2 = false;
        count++;
    }
    for (i = 0; i < record_n; i++)
        printf("%s %d\n", record[i], record_num[i]);
    for (i = 0; i < count; i++)
        free(pwrong[i]);
    free(pwrong);
    free(record);
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

  • HJ20 密码验证合格程序(字符串)

华为机试 108 题(C 语言解答)_第21张图片

输入:
021Abc9000
021Abc9Abc1
021ABC9000
021$bc9000

输出:
OK
NG
NG
OK

示例代码:HJ20.c


#include 
#include 
#include 
#include 
#define LEN 101

char * s_gets(char * st, int n);
void cut_str(char * dest, char * start, char * end);
bool is_include(char * st_1, char * st_2);
int get_max(char * st_1, char * st_2);
bool is_good(char * str);

int main(void)
{
    char str[LEN];
    
    while (s_gets(str, LEN) != NULL && *str != '\0')
        printf("%s\n", is_good(str) ? "OK" : "NG");
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

void cut_str(char * dest, char * start, char * end)
{
    int i;
    
    for (i = 0; i <= end - start; i++)
        dest[i] = *(start + i);
    dest[i] = '\0';
}

bool is_include(char * st_1, char * st_2)
{
    int i, j;
    int len_1 = strlen(st_1);
    int len_2 = strlen(st_2);
    int count = 0;
    
    for (i = 0; i < len_1; i++)
    {
        for (j = count; j < len_2; j++)
        {
            if (st_2[j] == st_1[i])
            {
                count++;
                if (count == len_2)
                    return true;
                break;
            }
            else
            {
                if (count > 0)
                {
                    i-= count;
                    count = 0;
                }
                break;
            }
        }
    }
    
    return false;    
}

int get_max(char * st_1, char * st_2)
{
    char dest[LEN];
    int len_2 = strlen(st_2);
    int j;
    int time;
    
    time = len_2 - 2;
    for (j = 0; j < time; j++)
    {
        cut_str(dest, st_2 + j, st_2 + j + 2);
        if (is_include(st_1 + 3 + j, dest))
            return 1;    
    }
    
    return 0;
}

bool is_good(char * str)
{
    int len = strlen(str);
    int lo_ch = 0, up_ch = 0, num = 0, other = 0;
    int i;
    int count = 0;
    
    for (i = 0; i < len; i++)
    {
        if (islower(str[i]))
            lo_ch =1;
        else if (isupper(str[i]))
            up_ch = 1;
        else if (isdigit(str[i]))
            num = 1;
        else
            other = 1;
    }
    count += lo_ch + up_ch + num + other;
    if (len > 8 && !get_max(str, str) && count > 2)
        return true;
    
    return false;
}

HJ21 简单密码(字符串)

华为机试 108 题(C 语言解答)_第22张图片

输入:YUANzhi1987

输出:zvbo9441987

示例代码:HJ21.c


#include 
#include 
#include 
#define LEN 1001

char * s_gets(char * st, int n);
void lower_num(char * st);
void upper_lower(char * st);

int main(void)
{
    char str[LEN];
    
    if (s_gets(str, LEN) != NULL && *str != '\0')
    {
        lower_num(str);
        upper_lower(str);
    }
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

void lower_num(char * st)
{
    char str[8][5] = { "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
    int i;
    
    while (*st)
    {
        for (i = 0; i < 8; i++)
        if (strchr(str[i], *st))
            *st = i + 2 + '0';
        st++;
    }
}

void upper_lower(char * st)
{
    char * st_b = st;
    while (*st)
    {
        if (isupper(*st))
        {
            *st = tolower(*st);
            if (*st - 'a' == 25)
                *st = *st - 25;
            else
                *st = *st + 1;
        }
        st++;
    }
    puts(st_b);
}

  • HJ22 汽水瓶(基础数学)

华为机试 108 题(C 语言解答)_第23张图片

输入:
3
10
81
0

输出:
1
5
40

说明:
样例 1 解释:用三个空瓶换一瓶汽水,剩一个空瓶无法继续交换
样例 2 解释:用九个空瓶换三瓶汽水,剩四个空瓶再用三个空瓶换一瓶汽水,剩两个空瓶,向老板借一个空瓶再用三个空瓶换一瓶汽水喝完得一个空瓶还给老板    

示例代码HJ22.c


#include 
#define N 3

void get_water(int bottles);

int main(void)
{
    int num;
    
    while (scanf("%d", &num) == 1)
        get_water(num);
        
    return 0;
}

void get_water(int bottles)
{
    int water = 0;
    
    while (bottles >= 3)
    {
        water += bottles / 3;
        bottles = bottles % 3 + bottles / 3;
    }
    if (bottles > 1)
        water++;
    if (water)
        printf("%d\n", water);
}

  • HJ23 删除字符串中出现次数最少的字符(字符串)

华为机试 108 题(C 语言解答)_第24张图片

输入:aabcddd

输出:aaddd

示例代码:HJ23.c


#include 
#include 
#include 
#define LEN 21

char * s_gets(char * st, int n);
void delete_mini(char * st);

int main(void)
{
    char str[LEN];
    
    if (s_gets(str, LEN) != NULL && *str != '\0')
        delete_mini(str);
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

void delete_mini(char * st)
{
    int i, j;
    int len = strlen(st);
    static int stat[LEN];
    static char str[LEN];
    bool flag;
    int min;
    
    for (i = 0; i < len; i++)
    {
        flag = false;
        for (j = 0; j < (int) strlen(str); j++)
        {
            if (*(st + i) == *(str + j))
            {
                stat[j]++;
                flag = true;
                break;
            }
        }
        if (!flag)
        {
            stat[(int) strlen(str)] = 1;
            *(str + (int) strlen(str)) = *(st + i);
        }        
    }
    min = stat[0];
    for (i = 1; i < (int) strlen(str); i++)
    {
        if (min > stat[i])
            min = stat[i];    
    }
    while (*st)
    {
        for (i = 0; i < (int) strlen(str); i++)
        {
            if (*st == *(str + i) && stat[i] > min)
                putchar(*st);
        }
        st++;
    }
}

  • HJ24 合唱队(动态规划,最长子序列问题)

华为机试 108 题(C 语言解答)_第25张图片

输入:8
186 186 150 200 160 130 197 200

输出:4

说明:
由于不允许改变队列元素的先后顺序,所以最终剩下的队列应该为186 200 160 130或150 200 160 130     

示例代码:HJ24.c


#include 
#include 

int main(void)
{
    int n;
    int i, j;
    int * ar;
    int * dp_left, * dp_right;
    int max = 0;
    
    while (scanf("%d", &n) == 1)
    {
        ar = (int *) malloc(sizeof(int) * n);
        dp_left = (int *) malloc(sizeof(int) * n);
        dp_right = (int *) malloc(sizeof(int) * n);
        for (i = 0; i < n; i++) // 初始化没有比该数更小的 
        {
            scanf("%d", ar + i);
            dp_left[i] = 0;
            dp_right[i] = 0;
        }
        for (i = 1; i < n - 1; i++)
        {
            for (j = 0; j < i; j++)
            {
                if (ar[j] < ar[i])
                    dp_left[i] = (dp_left[i] < dp_left[j] + 1) ? dp_left[j] + 1 : dp_left[i];
            }
        }
        for (i = n - 2; i > 0; i--)
        {
            for (j = n - 1; j > i; j--)
            {
                if (ar[j] < ar[i])
                    dp_right[i] = (dp_right[i] < dp_right[j] + 1) ? dp_right[j] + 1 : dp_right[i];
            }
        }
        for (i = 1; i < n - 1; i++)
        {
            if (dp_left[i] && dp_right[i])
                max = (max > dp_left[i] + dp_right[i]) ? max : dp_left[i] + dp_right[i];
        }
        printf("%d\n", n - (max + 1));
        max = 0;
    }
    free(ar);
    free(dp_left);
    free(dp_right); 
    
    return 0;
}

  • HJ25 数据分类处理(排序)

华为机试 108 题(C 语言解答)_第26张图片
华为机试 108 题(C 语言解答)_第27张图片

输入:
15 123 456 786 453 46 7 5 3 665 453456 745 456 786 453 123
5 6 3 6 3 0

输出:
30 3 6 0 123 3 453 7 3 9 453456 13 453 14 123 6 7 1 456 2 786 4 46 8 665 9 453456 11 456 12 786

说明:
将序列R:5,6,3,6,3,0(第一个5表明后续有5个整数)排序去重后,可得0,3,6。
序列I没有包含0的元素。
序列I中包含3的元素有:I[0]的值为123、I[3]的值为453、I[7]的值为3、I[9]的值为453456、I[13]的值为453、I[14]的值为123。
序列I中包含6的元素有:I[1]的值为456、I[2]的值为786、I[4]的值为46、I[8]的值为665、I[9]的值为453456、I[11]的值为456、I[12]的值为786。
最后按题目要求的格式进行输出即可。     

示例代码:HJ25.c


#include 
#include 
#include 
#include 
#define LEN 100

typedef struct {
    int num;         // 规则数据 
    int count;       // 符合条件的数量 
    int id[LEN];
} Rule;

typedef Rule * Pr;

bool is_match(int rule, int data);   // 判断数据是否符合规则 
void pro_rule(Pr pRule, int * pR_n); // 处理规则数据(去重、排序) 

int main(void)
{
    int * list;          // 存储出现的数据 
    Pr rule;             // 记录出现的规则 
    int l_n;             // 记录待处理的数据
    int r_n;             // 记录规则数量 
    int total = 0;       // 记录符合规则的数量 
    int rule_count = 0;  // 记录不至少有一个数据符合规则的规则 
    bool find = false;   // 记录是否找到符合要求的规则 
    int i, j;
    
    while (scanf("%d", &l_n) == 1)
    {
        list = (int *) malloc(sizeof(int) * l_n);
        for (i = 0; i < l_n; i++)         // 读入待处理数据 
            scanf("%d", list + i);
        scanf("%d", &r_n);
        rule = (Pr) malloc(sizeof(Rule) * r_n);
        for (i = 0; i < r_n; i++)         // 读入规则 
        {
            scanf("%d", &(rule + i)->num);
            (rule + i)->count = 0; 
        }
        pro_rule(rule, &r_n);
        for (i = 0; i < r_n; i++)
        {
            for (j = 0; j < l_n; j++)
            {
                if (is_match(rule[i].num, list[j]))
                {
                    find = true;
                    rule[i].id[rule[i].count] = j;
                    rule[i].count++;
                    total++; 
                }        
            }
            if (find == true)
            {
                rule_count++;
                find = false;
            }
        }
        printf("%d ", (rule_count + total) * 2);
        for (i = 0; i < r_n; i++)
        {
            if (rule[i].count)
            {
                printf("%d %d ", rule[i].num, rule[i].count);
                for (j = 0; j < rule[i].count; j++)
                    printf("%d %d ", rule[i].id[j], list[rule[i].id[j]]);
            }
        }
        total = rule_count = 0;
    }
    
    free(list);
    free(rule);
    
    return 0;
}

bool is_match(int rule, int data)
{
    char str_r[LEN];
    char str_d[LEN];
    
    sprintf(str_r, "%d", rule);
    sprintf(str_d, "%d", data);
    if (strstr(str_d, str_r))
        return true;
    
    return false;
}

void pro_rule(Pr pRule, int * pR_n)
{
    int temp;
    int i, j;
    
    /* 排序 */ 
    for (i = 0; i < *pR_n - 1; i++)
    {
        for (j = i + 1; j < *pR_n; j++)
        {
            if ((pRule + i)->num > (pRule + j)->num)
            {
                temp = (pRule + i)->num;
                (pRule + i)->num = (pRule + j)->num;
                (pRule + j)->num = temp;
            }
        }
    }
    /* 去重 */
    for (i = 1, j = 0; i < *pR_n; i++)
    {
        temp = (pRule + j)->num;
        if ((pRule + i)->num != temp)
        {
            j++;
            (pRule + j)->num = (pRule + i)->num;
        }    
    }
    *pR_n = j + 1;
} 

  • HJ26 字符串排序(字符串)

华为机试 108 题(C 语言解答)_第28张图片

输入:A Famous Saying: Much Ado About Nothing (2012/8).

输出:A aaAAbc dFgghh: iimM nNn oooos Sttuuuy (2012/8).

示例代码:HJ26.c


#include 
#include 
#include 
#include 
#define LEN 1001
#define COUNT 125
#define SIZE 26

int main(void)
{
    char str[LEN];
    static int str_mark[LEN];
    static int lower[SIZE][COUNT];
    static int upper[SIZE][COUNT];
    static int lower_time[SIZE];
    static int upper_time[SIZE];
    int len = 0;
    int upper_len;
    int lower_len;
    int i, j, k;
    char ch;
    char up_ch, lo_ch;
    static int l_k, u_k;
    bool find_l, find_u;
    
    while ((ch = getchar()) != '\n')
    {
        str[len] = ch;
        if (isupper(ch))
        {
            upper[ch - 'A'][0]++;                // 出现的次数 
            upper_time[ch - 'A']++;              // 备份出现的次数 
            upper_len = upper[ch - 'A'][0];      // 更新该字符出现的次数 
            upper[ch - 'A'][upper_len] = len;    // 记录该字符出现的位置 
            str_mark[len] = 1;
        }
        else if (islower(ch))
        {
            lower[ch - 'a'][0]++;
            lower_time[ch - 'a']++;
            lower_len = lower[ch - 'a'][0];
            lower[ch - 'a'][lower_len] = len;
            str_mark[len] = 1;
        }    
        len++;
    }
    for (i = 0; i < len; i++)
    {
        if (str_mark[i] == 1)
        {
            find_l = false;
            find_u = false;
            for (j = 0; j < SIZE; j++)
            {
                if (upper[j][0] > 0)
                {
                    find_u = true;
                    up_ch = j + 'A';
                    break;
                }
            }
            for (k = 0; k < SIZE; k++)
            {
                if (lower[k][0] > 0)
                {
                    find_l = true;
                    lo_ch = k + 'a';
                    break;
                }
            }
            if (find_l && find_u)
            {
                if (lo_ch < tolower(up_ch))
                    ch = lo_ch;
                else if (lo_ch > tolower(up_ch))
                    ch = up_ch;
                else
                {
                    l_k = lower_time[k] - lower[k][0] + 1;
                    u_k = upper_time[j] - upper[j][0] + 1;
                    ch = lower[k][l_k] < upper[j][u_k] ? lo_ch : up_ch;
                }        
            }
            else if (find_l)
                ch = lo_ch;
            else
                ch = up_ch;        
            if (ch == lo_ch)
                lower[k][0]--;
            else
                upper[j][0]--;
            putchar(ch);
        }
        else
            putchar(str[i]);
    }
    
    return 0;
} 

  • HJ27 查找兄弟单词(字符串)

华为机试 108 题(C 语言解答)_第29张图片

输入:6 cab ad abcd cba abc bca abc 1

输出:
3
bca

说明:
abc的兄弟单词有cab cba bca,所以输出3
经字典序排列后,变为bca cab cba,所以第1个字典序兄弟单词为bca  

示例代码:HJ27.c


#include 
#include 
#include 
#include 
#define LEN 12
#define SIZE 26

bool is_brother(char * st_1, char * st_2);
void order(char ** pst, int n);

int main(void)
{
    int n;
    int sec;
    char temp[LEN];
    char ** pstr;
    char ** pbro;
    char * orig;
    int i;
    int count = 0;
    
    while (scanf("%d", &n) == 1)
    {
        pstr = (char **) malloc(sizeof(char *) * n);
        pbro = (char **) malloc(sizeof(char *) * n);
        for (i = 0; i < n; i++)
        {
            scanf("%s", temp);
            pstr[i] = (char *) malloc(sizeof(char) * ((int) strlen(temp) + 1));
            strcpy(pstr[i], temp);
        }
        scanf("%s", temp);
        orig = (char *) malloc(sizeof(char) * ((int) strlen(temp) + 1));
        strcpy(orig, temp);
        scanf("%d", &sec);
        for (i = 0; i < n; i++)
        {
            if (is_brother(pstr[i], orig))
                pbro[count++] = pstr[i];
        }
        printf("%d\n", count);
        if (sec <= count)
        {
            order(pbro, count);
            printf("%s\n", pbro[sec - 1]);
        }
    }
    for (i = 0; i < n; i++)
        free(pstr[i]);
    free(pstr);
    free(orig);
    free(pbro);
    
    return 0;
}

bool is_brother(char * st_1, char * st_2)
{
    int len_1 = strlen(st_1);
    int len_2 = strlen(st_2);
    int st_1ch[SIZE], st_2ch[SIZE]; 
    int i;
    
    memset(st_1ch, 0, sizeof(st_1ch));
    memset(st_2ch, 0, sizeof(st_2ch));
    if (len_1 != len_2)
        return false;
    if (strcmp(st_1, st_2) == 0)
        return false;
    for (i = 0; i < len_1; i++)
    {
        st_1ch[st_1[i] - 'a']++;
        st_2ch[st_2[i] - 'a']++;
    }
    for (i = 0; i < SIZE; i++)
    {
        if (st_1ch[i] != st_2ch[i])
            return false;
    }     
    
    return true;
}

void order(char ** pst, int n)
{
    int i, j;
    char * temp;
    
    for (i = 0; i < n - 1; i++)
    {
        for (j = i + 1; j < n; j++)
        {
            if (strcmp(pst[i], pst[j]) > 0)
            {
                temp = pst[i];
                pst[i] = pst[j];
                pst[j] = temp;    
            }
        }
    }
}

  • HJ28 素数伴侣(二分图,匈牙利算法)

华为机试 108 题(C 语言解答)_第30张图片

示例代码:HJ28.c


#include 
#include 
#include 
#include 

/* 判断是否为素数 */ 
bool IsPrime(int num);
/* 标记所有能够匹配的素数伴侣对 */ 
void MarkMate(int evenN, int oddN, int * even, int * odd, bool ** mark);
/* 判断当前偶数能够匹配到一个未被匹配的奇数 */ 
bool FindPrimeMate(int num, int oddN, bool ** mark, bool * used, int * evenIdOfOdd);

int main(void)
{
    int n;             // 一个正偶数,保存要输入的数的个数 
    int * ar;          // 保存输入的数字
    int * even;        // 保存奇数
    int * odd;         // 保存偶数
    int evenN = 0;     // 保存偶数数量
    int oddN = 0;      // 保存奇数数量
    bool ** mark;      // 记录所有能够匹配的奇数和偶数下标
    bool * used;       // 记录目前该奇数是否已被使用 
    int * evenIdOfOdd; // 记录与奇数匹配的偶数的下标 
    int temp;          // 临时保存输入的数
    int count = 0;     // 记录匹配对数 
    int i, j;
    
    while (scanf("%d", &n) == 1)
    {
        ar = (int *) malloc(sizeof(int) * n);
        even = (int *) malloc(sizeof(int) * n);
        odd = (int *) malloc(sizeof(int) * n);
        for (i = 0; i < n; i++)
        {
            scanf("%d", &temp);
            if (0 == temp % 2)
                even[evenN++] = temp;
            else
                odd[oddN++] = temp;
        }
        mark = (bool **) malloc(sizeof(bool *) * evenN);
        used = (bool *) malloc(sizeof(bool) * oddN);
        for (i = 0; i < evenN; i++)
            mark[i] = (bool *) malloc(sizeof(bool) * oddN);
        for (i = 0; i < evenN; i++)
        {
            for (j = 0; j < oddN; j++)
                mark[i][j] = false;
        }
        evenIdOfOdd = (int *) malloc(sizeof(int) * oddN);
        memset(evenIdOfOdd, -1, sizeof(int) * oddN);
        /* 标记能够匹配的一对数字 */
        MarkMate(evenN, oddN, even, odd, mark);
        /* 开始配对 */
        for (i = 0; i < evenN; i++)
        {
            memset(used, false, sizeof(bool) * oddN);
            if (FindPrimeMate(i, oddN, mark, used, evenIdOfOdd))
                count++;
        }
        /* 配对完成 */ 
        printf("%d", count);
    }
    free(ar);
    free(even);
    free(odd);
    for (i = 0; i < evenN; i++)
        free(mark[i]);
    free(mark);
    free(evenIdOfOdd);
    
    return 0;
}

bool IsPrime(int num)
{
    int i;
    
    for (i = 2; i * i <= num; i++)
    {
        if (num % i == 0)
            return false;
    }
    
    return true;
}

void MarkMate(int evenN, int oddN, int * even, int * odd, bool ** mark)
{
    int i, j;
    
    for (i = 0; i < evenN; i++)
    {
        for (j = 0; j < oddN; j++)
        {
            if (IsPrime(even[i] + odd[j]))
                mark[i][j] = true;
        }
    }
    
}

/* 匈牙利算法 */ 
bool FindPrimeMate(int num, int oddN, bool ** mark, bool * used, int * evenIdOfOdd)
{
    int i;
    
    /* 找到第一个能够匹配的奇数,若该数已经被匹配,则尝试给该数对应的偶数
    再找一个新的数匹配并替代该数为当前偶数的匹配数,若找不到新的匹配数,则
    尝试找第二个能够匹配的奇数,若最终扫描到最后一个奇数仍然无法匹配成功,
    则匹配失败 */ 
    for (i = 0; i < oddN; i++)
    {
        if (mark[num][i] && !used[i])
        {
            used[i] = true;
            if (evenIdOfOdd[i] == -1 || FindPrimeMate(evenIdOfOdd[i], oddN, mark, used, evenIdOfOdd))
            {
                evenIdOfOdd[i] = num;
                return true;
            }
        }
    }
    
    return false;
}

  • HJ29 字符串加解密(字符串)

华为机试 108 题(C 语言解答)_第31张图片

输入:
abcdefg
BCDEFGH

输出:
BCDEFGH
abcdefg

示例代码:HJ29.c


#include 
#include 
#include 
#define LEN 1001

void enc(char * st);
void dec(char * st);

int main(void)
{
    char str_ori[LEN];
    char str_sec[LEN];
    
    while (scanf("%s%s", str_ori, str_sec) == 2)
    {
        enc(str_ori);
        dec(str_sec);
    }
    
    return 0;
}

void enc(char * st)
{
    static char str[LEN];
    int len = 0;
    
    while (*st)
    {
        if (islower(*st))
            str[len++] = toupper((*st - 'a' + 1) % 26 + 'a');
        else if (isupper(*st))
            str[len++] = tolower((*st - 'A' + 1) % 26 + 'A');
        else
            str[len++] = (*st - '0' + 1) % 10 + '0';
        st++;
    }
    puts(str);
}

void dec(char * st)
{
    static char str[LEN];
    int len = 0;
    
    while (*st)
    {
        if (islower(*st))
            str[len++] = toupper((*st - 'a' - 1 + 26) % 26 + 'a');
        else if (isupper(*st))
            str[len++] = tolower((*st - 'A' - 1 + 26) % 26 + 'A');
        else
            str[len++] = (*st - '0' - 1 + 10) % 10 + '0';
        st++;
    }
    puts(str);
}

  • HJ30 字符串合并处理(字符串)

华为机试 108 题(C 语言解答)_第32张图片

输入:
ab CD

输出:
3B5D

说明:
合并后为abCD,按奇数位和偶数位排序后是CDab(请注意要按ascii码进行排序,所以C在a前面,D在b前面),转换后为3B5D    

示例代码:HJ30.c


#include 
#include 
#include 
#include 
#define LEN 101

void order(char * st);              // 排序字符串 
void trans(char * st);              // 转换字符串 
char proCh(char ch);                // 转换字符 

int main(void)
{
    
    static char str[LEN * 2];       // 保存合并后的字符串
    char temp[LEN];                 // 第二个字符串
    
    while (scanf("%s%s", str, temp) == 2)
    {
        strcat(str, temp);
        order(str);
        trans(str); 
    }
    
    return 0;
}

void order(char * st)
{
    int i, j;
    int len = strlen(st);
    char temp;
    
    if (len < 3)
        return;
    /* 排列偶数位 */
    for (i = 0; st[i + 2] != '\0'; i += 2)
    {
        for (j = i + 2; st[j] != '\0'; j += 2)
        {
            if (st[i] > st[j])
            {
                temp = st[i];
                st[i] = st[j];
                st[j] = temp;
            }
        }    
    }
    /* 排列奇数位 */
    for (i = 1; st[i + 2] != '\0'; i += 2)
    {
        for (j = i + 2; st[j] != '\0'; j += 2)
        {
            if (st[i] > st[j])
            {
                temp = st[i];
                st[i] = st[j];
                st[j] = temp;
            }
        }    
    } 
}

void trans(char * st)
{
    while (*st)
    {
        if ((*st >= 'a' && *st <= 'f')|| (*st >= 'A' && *st <= 'F')
            || isdigit(*st))
            *st = proCh(*st);
        putchar(*st);
        st++;
    }
}

char proCh(char ch)
{
    int temp;
    int i;
    int num = 0;
    
    if (isupper(ch))
        ch = tolower(ch);
    if (isalpha(ch))
        temp = ch - 'a' + 10;
    else
        temp = ch - '0';
    for (i = 0; i < 4; i++)
        num = 2 * num + ((temp >> i) & 1) ;
    if (num > 9)
        ch = toupper(num - 10 + 'a');
    else
        ch = num + '0';
    
    return ch;
} 

  • HJ31 单词倒排

华为机试 108 题(C 语言解答)_第33张图片

输入:
I am a student

输出:
student a am I

示例代码:HJ31.c


#include 
#include 
#include 
#define LEN 10001

char * s_gets(char * st, int n);
void reverse(char * st);

int main(void)
{
    char str[LEN];
    if (s_gets(str, LEN) != NULL && *str != '\0')
        reverse(str);
        
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

void reverse(char * st)
{
    int i;
    
    for (i = (int) strlen(st) - 1; i > -1; i--)
    {
        if (!isalpha(*(st + i)))
        {
            *(st + i) = '\0';
            printf("%s ", st + i + 1);
        }
        if (i == 0 && isalpha(*st))
            printf("%s", st);
    }
}

  • HJ32 密码截取(字符串,最长回文子串问题)

华为机试 108 题(C 语言解答)_第34张图片

输入:
ABBA

输出:
4

示例代码:HJ32.c


#include 
#include 
#define LEN 2501

int get_max(char * st);

int main(void)
{
    char str[LEN];
    
    while (scanf("%s", str) == 1)
        printf("%d", get_max(str));
    
    return 0;
}

int get_max(char * st)
{
    int i, j;
    int le, ri;
    int len = strlen(st);
    int max = 0;

    for (i = 0; i < len - 1; i++)
    {
        for (j = i + 1; j < len; j++)
        {
            le = i;
            ri = j;
            while (le < ri)
            {
                if (st[le] != st[ri])
                {
                    break;
                }    
                else
                {
                    le++;
                    ri--;
                }
            }
            if (le >= ri)
                max = (max > j - i + 1) ? max : j - i + 1; 
        }
    }
    
    return max;
}

  • HJ33 整数与IP地址间的转换(字符串,位运算)

华为机试 108 题(C 语言解答)_第35张图片

输入:
10.0.3.193
167969729

输出:
167773121
10.3.3.193

示例代码:HJ33.c


#include 
#include 
#define SIZE 8
#define LEN 32

void dec_bin(long int num, char * st);
void dec_bin32(long long int num, char * st);
void bin_dec(char * st);
void cut_str(char * dest, char * start, char * end);

int main(void)
{
    static char st_1[SIZE + 1];
    static char st_2[SIZE + 1];
    static char st_3[SIZE + 1];
    static char st_4[SIZE + 1];
    static char str[4 * SIZE + 1];
    int ip_1, ip_2, ip_3, ip_4;
    long long int ip;
    
    scanf("%d.%d.%d.%d", &ip_1, &ip_2, &ip_3, &ip_4);
    dec_bin(ip_1, st_1);
    dec_bin(ip_2, st_2);
    dec_bin(ip_3, st_3);
    dec_bin(ip_4, st_4);
    strcat(str, st_1);
    strcat(str, st_2);
    strcat(str, st_3);
    strcat(str, st_4);
    bin_dec(str);
    putchar('\n');
    scanf("%lld", &ip);
    dec_bin32(ip, str);
    cut_str(st_1, str, str + 7);
    cut_str(st_2, str + 8, str + 15);
    cut_str(st_3, str + 16, str + 23);
    cut_str(st_4, str + 24, str + 31);
    bin_dec(st_1);
    putchar('.');
    bin_dec(st_2);
    putchar('.');
    bin_dec(st_3);
    putchar('.');
    bin_dec(st_4);
    putchar('\n');
    
    return 0;
}


void dec_bin(long int num, char * st)
{
    int i, j;
    char str[SIZE + 1];
    
    for (i = 0; i < SIZE; i++)
    {
        str[i] = (num & 1) + '0';
        num >>= 1;
    }
    for (i = 0, j = SIZE - 1; i < SIZE; i++, j--)
        st[i] = str[j];
}

void dec_bin32(long long int num, char * st)
{
    int i, j;
    char str[LEN + 1];
    
    for (i = 0; i < LEN; i++)
    {
        str[i] = (num & 1) + '0';
        num >>= 1;
    }
    for (i = 0, j = LEN - 1; i < LEN; i++, j--)
        st[i] = str[j];
}

void bin_dec(char * st)
{
    long long int num = 0;
    
    while (*st)
    {
        num = 2 * num + *st - '0';
        st++;
    }
    printf("%lld", num);
}

void cut_str(char * dest, char * start, char * end)
{
    int i;
    
    for (i = 0; i <= end - start; i++)
        dest[i] = *(start + i);
}

  • HJ34 图片整理(字符串)

华为机试 108 题(C 语言解答)_第36张图片

输入:
Ihave1nose2hands10fingers

输出:
0112Iaadeeefghhinnnorsssv

示例代码:HJ34.c


#include 
#include 
#define LEN 1001

char * s_gets(char * st, int n);
void ascii_up(char * st);

int main(void)
{
    char str[LEN];
    
    if (s_gets(str, LEN) != NULL && *str != '\0')
        ascii_up(str);
    puts(str);
    
    return 0; 
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n')
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

void ascii_up(char * st)
{
    int i, j;
    char ch;
    int len;
    
    len = strlen(st);
    
    for (i = 0; i < len - 1; i++)
    {
        for (j = i + 1; j < len; j++)
        {
            if (*(st + i) > *(st + j))
            {
                ch = *(st + i);
                *(st + i) = *(st + j);
                *(st + j) = ch;
            }
        }
    }
}

  • HJ35 蛇形矩阵(基础数学,数组)

华为机试 108 题(C 语言解答)_第37张图片

输入:
4

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

示例代码:HJ35.c


#include 

void snack_matrix(int n);

int main(void)
{
    int num;
    
    scanf("%d", &num);
    snack_matrix(num);
    
    return 0;
}

void snack_matrix(int n)
{
    int i, j;
    int start = 1;
    int num;
    
    for (i = n; i > 0; i--)
    {
        start += n - i;
        num = start;
        for (j = 1; j <= i; j++)
        {
            if (j == 1)
                printf("%d ", start);
            else
                printf("%d ",  num += j + n - i);    
        }
        putchar('\n');
    }    
}

  • HJ36 字符串加密(字符串)


输入:
nihao
ni

输出:
le

示例代码:HJ36.c


#include 
#define LEN 26

int main(void)
{
    static int ar[LEN];
    static char code[LEN];
    char ch;
    int i;
    int len = 0;
    
    while ((ch = getchar()) != '\n')
    {
        ar[ch - 'a']++;
        if (ar[ch - 'a'] == 1)
            code[len++] = ch;
    }
    for (i = 0; i < LEN; i++)
    {
        if (!ar[i])
            code[len++] = 'a' + i;
    }
    while ((ch = getchar()) != '\n')
        putchar(code[ch - 'a']);
    
    return 0;        
}

  • HJ37 统计每个月兔子的总数(排序,斐波拉契数列)

华为机试 108 题(C 语言解答)_第38张图片

输入:
3

输出:
2

示例代码:HJ37.c


#include 

int main(void)
{
    int time;
    int i;
    
    scanf("%d", &time);
    int value[time + 1];
    value[1] = value[2] = 1;
    for (i = 3; i <= time; i++)
        value[i] = value[i - 2] + value[i - 1];
    printf("%d", value[time]);
    
    return 0;
} 

  • HJ38 求小球落地5次后所经历的路程和第5次反弹的高度(基础数学)

华为机试 108 题(C 语言解答)_第39张图片

输入:
1

输出:
2.875
0.03125

示例代码:HJ38.c


#include 

void print_info(int n);

int main(void)
{
    int meters;
    
    scanf("%d", &meters);
    print_info(meters);
    
    return 0; 
}

void print_info(int n)
{
    float up_meter = n;
    float total = n;
    int times = 4;
    
    while (times)
    {
        up_meter = up_meter / 2;
        total += up_meter * 2;
        times--;
    }
    up_meter /= 2;
    
    printf("%.6f\n%.6f\n", total, up_meter);
}

  • HJ39 判断两个IP是否属于同一子网(字符串)

华为机试 108 题(C 语言解答)_第40张图片
华为机试 108 题(C 语言解答)_第41张图片
华为机试 108 题(C 语言解答)_第42张图片

输入:
255.255.255.0
192.168.224.256
192.168.10.4
255.0.0.0
193.194.202.15
232.43.7.59
255.255.255.0
192.168.0.254
192.168.0.1

输出:
1
2
0

说明:
对于第一个例子:
255.255.255.0
192.168.224.256
192.168.10.4
其中IP:192.168.224.256不合法,输出1

对于第二个例子:
255.0.0.0
193.194.202.15
232.43.7.59
2个与运算之后,不在同一个子网,输出2

对于第三个例子,2个与运算之后,如题目描述所示,在同一个子网,输出0

示例代码:HJ39.c


#include 
#include 
#include 
#include 
#include 
#define LEN 20

bool IsLegalIp(char * st);
bool IsLegalMask(char * st);
bool IsSubNet(char * mask, char * ip1, char * ip2);

int main(void)
{
    char mask[LEN];       // 掩码 
    char mask_b[LEN];     // 备份掩码, 注意不要对同一字符串重复分割(strtok()) 
    char ip1[LEN];        // 第一个 ip
    char ip2[LEN];        // 第二个ip
    
    while (scanf("%s%s%s", mask, ip1, ip2) == 3)
    {
        strcpy(mask_b, mask); 
        if (!(IsLegalMask(mask)) || !(IsLegalIp(ip1)) 
            || !(IsLegalIp(ip2)))
            printf("1\n");
        else if (IsSubNet(mask_b, ip1, ip2))
            printf("0\n");
        else
            printf("2\n");    
    } 
    
    return 0;
}

bool IsLegalIp(char * st)
{
    char * st_b = st;
    int num_count = 0;
    int dot_count = 0;
    int num = 0;
    
    while (*st)
    {
        if ((st == st_b  && !(*st >= '0' && *st <= '9')) 
            || (*st == '.' && !(*(st + 1) >= '0' && *(st + 1) <= '9')))
            return false;
        if (st == st_b && *st == '0' && isdigit(*(st + 1)))
            return false;
        if (*st == '.' && *(st + 1) == '0' && isdigit(*(st + 2)))
            return false;
        if (isdigit(*st))
        {
            num = 10 * num + *st - '0';
            if (!isdigit(*(st + 1)))
                num_count++;    
        }    
        if (*st == '.')
        {
            dot_count++;
            if (!(num >= 0 && num < 256))
                return false;    
            num = 0;
        }    
        st++;
    }
    if (!(num_count == 4 && dot_count == 3) || !(num >= 0 && num < 256))
        return false;
    
    return true;
}

bool IsLegalMask(char * st)
{
    char * mask_part;
    int num;
    int i, j;
    bool count_zero = false;
    int count_one = 0;
    int temp; 
    
    mask_part = strtok(st, ".");
    for (i = 0; i < 4; i++)
    {
        num = atoi(mask_part);
        if (num == 255)
            count_one++;
        if ((i == 0 && num == 0) || num < 0 || num > 255)
            return false;
        for (j = 0; j < 8; j++)
        {

            temp = (num >> (7 - j)) & 1;
            if (temp == 0)
                count_zero = true;
            if (temp == 1 && count_zero)
                return false;
        }
        if (i < 3)
            mask_part = strtok(NULL, ".");
    }
    if (count_one == 4)
        return false;
    
    return true;
}

bool IsSubNet(char * mask, char * ip1, char * ip2)
{
    int ip1_p[4];
    int ip2_p[4];
    int mask_p[4];
    int temp1;
    int temp2;
    char * temp = NULL;
    int i, j;
    
    temp = strtok(mask, ".");
    for (i = 0; i < 4; i++)
    {
        mask_p[i] = atoi(temp);
        if (i < 3)
            temp = strtok(NULL, ".");
    }
    temp = strtok(ip1, ".");
    for (i = 0; i < 4; i++)
    {
        ip1_p[i] = atoi(temp);
        if (i < 3)
            temp = strtok(NULL, ".");
    }
    temp = strtok(ip2, ".");
    for (i = 0; i < 4; i++)
    {
        ip2_p[i] = atoi(temp);
        if (i < 3)
            temp = strtok(NULL, ".");
    }
    for (i = 0; i < 4; i++)
    {
        for (j = 0; j < 8; j++)
        {
            temp1 = ((ip1_p[i] >> j) & 1) & ((mask_p[i] >> j) & 1);
            temp2 = ((ip2_p[i] >> j) & 1) & ((mask_p[i] >> j) & 1);
            if (temp1 != temp2)
                return false;
        }
    }
    
    return true;
}

  • HJ40 统计字符(字符串)

华为机试 108 题(C 语言解答)_第43张图片

输入:
1qazxsw23 edcvfr45tgbn hy67uj m,ki89ol.\\/;p0-=\\][

输出:
26
3
10
12

示例代码:HJ40.c


#include 
#include 
#include 
#define LEN 1001

char * s_gets(char * st, int n);
void get_count(char * st);

int main(void)
{
    char str[LEN];
    
    if (s_gets(str, LEN) != NULL && *str != '\0') 
        get_count(str);
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

void get_count(char * st)
{
    int ch_count = 0, space_count = 0, num_count = 0, other_count = 0;
    
    while (*st)
    {
        if (isalpha(*st))
            ch_count++;
        else if (isspace(*st))
            space_count++;
        else if (isdigit(*st))
            num_count++;
        else
            other_count++;
        st++;
    }
    printf("%d\n%d\n%d\n%d\n", ch_count, space_count, num_count, other_count);
}

  • HJ41 称砝码(基础数学)

华为机试 108 题(C 语言解答)_第44张图片

输入:
2
1 2
2 1

输出:
5

说明:
可以表示出0,1,2,3,4五种重量。 

示例代码:HJ41.c


#include 
#include 

int get_type(int n, int heav[], int num[]);

int main(void)
{
    int n;
    int i;
    
    while (scanf("%d", &n) == 1)
    {
        int heav[n], num[n];
        for (i = 0; i < n; i++)
            scanf("%d", heav + i);
        for (i = 0; i < n; i++)
            scanf("%d", num + i);
        printf("%d", get_type(n, heav, num));
    }
    
    return 0;
}

int get_type(int n, int heav[], int num[])
{
    int i, j, k;
    int max = 0;
    int count = 0;
    
    for (i = 0; i < n; i++)
        max += heav[i] * num[i];
    int mark[max + 1];
    for (i = 1; i <= max; i++)
        mark[i] = 0;
    mark[0] = 1;
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < num[i]; j++)
        {
            for (k = max; k >= 0; k--)
            {
                if (mark[k])
                    mark[k + heav[i]] = 1;
            }
        }
    } 
    
    for (i = 0; i <= max; i++)
        if (mark[i])
            count++;
    
    return count;
}

  • HJ42 学英语

华为机试 108 题(C 语言解答)_第45张图片
华为机试 108 题(C 语言解答)_第46张图片

输入:
22

输出:
twenty two

示例代码:HJ42.c


#include 
#include 
#include 

void get_bits(int * ar, long n);
void print_bits(int num, char ** s1, char ** s2, char ** s3);

int main(void)
{
    long n;                            // 保存输入数字
    static int bits[4];                // 获取不同的位的数量 
    char * s1[20] = { "", "one", "two", "three", "four", "five",
        "six", "seven", "eight", "nine", "ten", "eleven", "twelve",
        "thirteen", "fourteen", "fifteen", "sixteen", "seventeen",
        "eighteen", "nineteen" };
    char * s2[10] = { "", "", "twenty", "thirty", "forty", "fifty",
        "sixty", "seventy", "eighty", "ninety" };
    char * s3[4] = { "hundred", "thousand", "million", "billion" };
    bool flag = false;
    
    while (scanf("%ld", &n) == 1)
    {
        get_bits(bits, n);
        if (bits[3])
        {
            print_bits(bits[3], s1, s2, s3);
            printf(" %s", s3[3]);
            flag = true;
        }
        if (bits[2])
        {
            if (flag)
                putchar(' ');
            print_bits(bits[2], s1, s2, s3);
            printf(" %s", s3[2]);
            flag = true;
        }
        if (bits[1])
        {
            if (flag)
                putchar(' ');
            print_bits(bits[1], s1, s2, s3);
            printf(" %s", s3[1]);
            flag = true;
        }
        if (bits[0])
        {
            if (flag)
                putchar(' ');
            print_bits(bits[0], s1, s2, s3);
        }
        putchar('\n');
    }
    
    return 0;    
}

void get_bits(int * ar, long n)
{
    ar[0] = n % 1000;
    ar[1] = (n / 1000) % 1000;             // thousand
    ar[2] = (n / (1000 * 1000)) % 1000;    // million
    ar[3] = n / (1000 * 1000 * 1000);      // billion 
}

void print_bits(int num, char ** s1, char ** s2, char ** s3)
{
    bool flag = false;
    
    if (num >= 100)
    {
        printf("%s %s", s1[num / 100], s3[0]);
        flag = true;
        num %= 100;
    }
    if (num >= 20)
    {
        if (flag)
            printf(" and ");
        printf("%s", s2[num / 10]);
        num %= 10;
        if (num)
            printf(" %s", s1[num]);
    }
    else if (num)
    {
        if (flag)
            printf(" and ");
        printf("%s", s1[num]);
    }
}

HJ43 迷宫问题(DFS)

华为机试 108 题(C 语言解答)_第47张图片

输入:
5 5
0 1 0 0 0
0 1 1 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

输出:
(0,0)
(1,0)
(2,0)
(2,1)
(2,2)
(2,3)
(2,4)
(3,4)
(4,4)

示例代码:HJ43.c


#include 
#include 

bool DFS(int m, int n, int maze[][n], int visa[][n], int stack[][2], int x, int y, int top);

int main(void)
{
    int m, n;                 // m 行 n 列 
    int i, j;
    int top = 0;
    
    scanf("%d%d", &m, &n);
    int maze[m][n];           // 表示迷宫 
    int visa[m][n];           // 是否经过 
    int stack[m * n][2];      // 记录路径的坐标 
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++)
        {
            scanf("%d", *(maze + i) + j);
            visa[i][j] = 0;
        }
    }
    for (i = 0; i < m * n; i++)
    {
        stack[i][0] = 0;
        stack[i][1] = 0;
    }
    DFS(m, n, maze, visa, stack, 0, 0, top);
    
    return 0;
}

bool DFS(int m, int n, int maze[][n], int visa[][n], int stack[][2], int x, int y, int top)
{
    int i;
    
    /* 递归出口 */ 
    if (x == m - 1 && y == n - 1)
    {
        stack[top][0] = x;
        stack[top][1] = y;
        for (i = 0; i <= top; i++)
            printf("(%d,%d)\n", stack[i][0], stack[i][1]);
        return true;
    } 
    /* 如果超出界限或者已经经过或者是墙 */ 
    else if (x >= m || x < 0 || y >= n || y < 0 || visa[x][y] || maze[x][y])
        return false;
    else
    {
        visa[x][y] = 1;
        stack[top][0] = x;
        stack[top][1] = y;
        top++;
        /* 尝试向上、下、左、右 方法走 */ 
        if (DFS(m, n, maze, visa, stack, x - 1, y, top) || DFS(m, n, maze, visa, stack, x + 1, y, top)
            || DFS(m, n, maze, visa, stack, x, y - 1, top) || DFS(m, n, maze, visa, stack, x, y + 1, top))
            return true;
        /* 若四个方向都走不通,则回溯,但没有必要回溯的信息,top是个复制的参数,且走不通的路没必要再走 */ 
    }
    
    return false;
}

  • HJ44 Sudoku(DFS)

华为机试 108 题(C 语言解答)_第48张图片
华为机试 108 题(C 语言解答)_第49张图片

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

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

示例代码:HJ44.c


#include 
#include 
#define LEN 9

int DFS(int map[][LEN], int pos, int (*popen)[2], int count);
int islegal(int map[][LEN], int x, int y, int num);

int main()
{
    int map[LEN][LEN];
    int pos = 0;
    int i, j; 
    int count = 0;
    int open[LEN * LEN][2]; 
    
    /* 读入数据并记录空位 */ 
    for (i = 0; i < LEN; i++)
    {
        for (j = 0; j < LEN; j++)
        {
            scanf("%d", &map[i][j]);
            if (!map[i][j])
            {
                open[count][0] = i;
                open[count++][1] = j;
            }
        }
    }
    /* 深度优先遍历 */ 
    if (DFS(map, pos, open, count))
    {
        putchar('\n') ;
        for (i = 0; i < LEN; i++)
        {
            for (j = 0; j < LEN; j++)
                printf("%d ", map[i][j]);
            printf("\n");
        }
    }
    
    return 0;
}

/* pos 给第 pos个缺位匹配数值 pos 0 ~ count - 1。 DFS 本质就是穷举,找到一条成功的
路线之后不断返回上一层,return true,return true...,直到最上面一层,不需要要所有情况
都成功,只需要一条成功则达到目的。而所谓回溯实质上是退回对某个地址的值的改变。回溯与
否看会不会对其他路线造成影响,若会,则消除改变(如对数组和指针进行操作,则会改变该地
址的值),否则,则可不必回溯(如参数只是一个复制)。此外DFS不是多线程,所有路线是一次
一次尝试的,尝试到成功则停止,类似于树的遍历算法,也就意味着后面的操作可能会受到前面操
作的影响(例如改变了数组的值会对后面的计算判断造成影响,此时请务必回溯。)*/ 
int DFS(int map[][LEN], int pos, int (*popen)[2], int count)
{
    int x, y;
    int i;
    
    if (pos == count) /* 递归出口,填满了 */ 
        return 1;
    x = popen[pos][0];
    y = popen[pos][1];
    /* 尝试填入数字 */ 
    for (i = 1; i <= 9; i++)
    {
        if (islegal(map, x, y, i))
        {
            map[x][y] = i;
            if (DFS(map, pos + 1, popen, count))
                return 1;
            /* 回溯,目的是不对之后合法性计算造成影响,此处传递的是地址,故类似于全局变量 */ 
            map[x][y] = 0;
        }
    }
    
    return 0;
}

int islegal(int map[][LEN], int x, int y, int num)
{
    int ret = 1;
    int cx, cy;
    int i, j; 
    
    /* 判断填入行是否合法 */ 
    for (i = 0; i < LEN; i++)
    {
        if (i != x && num == map[i][y])
            return 0; 
    }
    /* 判断填入列是否合法 */ 
    for (j = 0; j < LEN; j++)
    {
        if (j != y && num == map[x][j])
            return 0;
    }
    /* 判断所在九宫格是否合法 */ 
    cx = x / 3;
    cy = y / 3;
    for (i = cx * 3; i < cx * 3 + 3; i++)
    {
        for (j = cy * 3; j < cy * 3 + 3; j++)
        {
            if ((i != x || j != y) && num == map[i][j])
                return 0;
        }
    }
    
    return ret;
}

  • HJ45 名字的漂亮度(字符串)

华为机试 108 题(C 语言解答)_第50张图片

输入:
2
zhangsan
lisi

输出:
192
101

说明:
对于样例lisi,让i的漂亮度为26,l的漂亮度为25,s的漂亮度为24,

示例代码:HJ45.c


#include 
#define LEN 26

int main(void)
{
    static int ar[LEN];
    int i, j;
    int n;
    char ch;
    int max = 0;
    int score = 26;
    int total_score = 0;
    
    scanf("%d", &n);
    getchar();
    for (i = 0; i < n; i++)
    {
        while ((ch = getchar()) != '\n')
        {
            ar[ch - 'a']++;
            if (ar[ch - 'a'] > max)
                max = ar[ch - 'a'];
        }
        while (max)
        {
            for (j = 0; j < LEN; j++)
            {
                if (ar[j] == max)
                {
                    total_score += score * max;
                    score--;
                }
            }    
            max--;
        }
        printf("%d\n", total_score);
        score = 26;
        max = total_score = 0;
        memset(ar, 0, sizeof(int) * LEN);
    }
    
    return 0;
}

  • HJ46 截取字符串(字符串)

华为机试 108 题(C 语言解答)_第51张图片

输入:
abABCcDEF
6

输出:
abABCc

示例代码:HJ46.c


#include 
#include 
#define LEN 1001

char * s_gets(char * st, int n);
char * get_n_word(char * st, int n);

int main(void)
{
    char str[LEN];
    int n;
    
    if (s_gets(str, LEN) != NULL && *str != '\0')
    {
        scanf("%d", &n);
        printf("%s", get_n_word(str, n));
    }    
        
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

char * get_n_word(char * st, int n)
{
    if (n > (int) strlen(st))
        return NULL;
    else
        *(st + n) = '\0';
    
    return st;
}

  • HJ48 从单向链表中删除指定值的节点(带头结点的单向链表)

华为机试 108 题(C 语言解答)_第52张图片
华为机试 108 题(C 语言解答)_第53张图片

输入:
5 2 3 2 4 3 5 2 1 4 3

输出:
2 5 4 1

说明:
形成的链表为2->5->3->4->1
删掉节点3,返回的就是2->5->4->1  

示例代码:HJ48.c


#include 
#include 
#include 

typedef struct node{
    int n_num;
    struct node * next;
} Node; 

typedef Node * List;

/* 初始化要改变头指针的值,因此要用指针 */ 
bool initia(List * list, int num);
/* 如果不需要在头节点之后插入值,则不需要头节点指针 */ 
bool insert(List list, int ins_num, int num);
/* 考虑到删除头节点,加指针 */ 
void dele_num(List * list, int del_num);
/* 打印节点,不需要指针 */ 
void show_list(List list);
/* 改变头节点的位置,需要头节点的指针 */ 
void free_list(List * list);

int main(void)
{
    List head = NULL;
    int total;
    int h_num;
    int i;
    int i_num, af_num;
    int del_num;
    
    scanf("%d%d", &total, &h_num);
    initia(&head, h_num);
    for (i = 0; i < total - 1; i++)
    {
        scanf("%d%d", &i_num, &af_num);
        if (!insert(head, i_num, af_num))
        {
            puts("Wrong!\n");
            exit(EXIT_FAILURE);
        }
            
    }
    scanf("%d", &del_num);
    dele_num(&head, del_num);
    show_list(head);
    free_list(&head);
    
    return 0;
}

bool initia(List * list, int num)
{
    *list = (List) malloc(sizeof(Node));
    if (*list != NULL)
    {
        (*list)->n_num = num;
        return true;
    }
    
    return false;
}

bool insert(List list, int ins_num, int num)
{
    bool find = false;
    List temp = list;
    List new_node;
    
    while (temp != NULL)
    {
        if (temp->n_num == num)
        {
            find = true;
            break;
        }
        temp = temp->next;    
    }
    if (find)
    {
        new_node = (List) malloc(sizeof(Node));
        if (new_node != NULL)
        {
            new_node->n_num = ins_num;
            new_node->next = temp->next;
            temp->next = new_node;
        }
        else
            return false;
    }
    else
        return false;
    
    return true;
}

void dele_num(List * list, int del_num)
{
    List temp = *list;
    List pre;
    bool find;
    
    while (temp != NULL)
    {
        if (temp->n_num == del_num)
        {
            find = true;
            break;
        }
        pre = temp;
        temp = temp->next;
    }
    if (find)
    {
        if (temp == *list)
        {
            *list = (*list)->next;
            free(temp);
        }
        else
        {
            pre->next = temp->next;
            free(temp);
        }
    }
}

void show_list(List list)
{
    while (list != NULL)
    {
        printf("%d ", list->n_num);
        list = list->next;
    }
}

void free_list(List * list)
{
    List temp;
    
    while (*list != NULL)
    {
        temp = *list;
        *list = (*list)->next;
        free(temp);
    }
}

  • HJ50 四则运算(栈,表达式求值,中缀转后缀与后缀转中缀算法的结合)

华为机试 108 题(C 语言解答)_第54张图片

输入:
3+2*{1+2*[-4/(8-6)+7]}

输出:
25

示例代码:HJ50.c


#include 
#include        // 提供 strchr() 函数原型
#include 
#define LEN 1001          // 多一个给空字符

// 对表达式字符串进行求值
int get_value(char * st);

// 对两个整数进行指定符号计算并返回 
int compute(int num1, int num2, char symbol);

// 获取最多 n - 1 个字符
char * s_gets(char * st, int n);

int main(void)
{
    char str[LEN];            // 获取保存的字符串
    
    if (s_gets(str, LEN) != NULL && *str != '\0')
        printf("%d", get_value(str));
    
    return 0;
}

int get_value(char * st)
{
    char symbol_stack[LEN];    // 符号栈,用于保存符号
    int number_stack[LEN];     // 数字栈,用于保存数字
    int top_s = -1;            // 符号栈顶标记为空栈
    int top_n = -1;               // 数字栈顶标记为空栈
    int n1, n2;                // 用于保存待计算的两个数字
    int temp;                  // 临时保存数字
    char * st_b = st;          // 备份字符串始址 
    
    while (*st)                // 遍历字符串 
    {
        // 左括号压入符号栈 
        if (*st == '(' || *st == '[' || *st == '{')
            symbol_stack[++top_s] = *st;
        // 处理数字,先处理正数,防止重复处理数字,例如 -1*(-1-1)
        if (isdigit(*st))
        {
            temp = 0;
            while (isdigit(*st))
                temp = temp * 10 + *st++ - '0';
            // 处理到非数字字符时,回退一个字符
                --st;
            // 将正数入栈
            number_stack[++top_n] = temp; 
        }
        // 处理负数或者减号
        if (*st == '-')
        {
            // 处理负数 
            if (st == st_b || *(st - 1) == '(' || *(st - 1) == '[' || *(st - 1) == '{')
            {
                temp = 0;
                while (isdigit(*++st))
                    temp = 10 * temp + *st - '0';
                // 负数入栈 
                number_stack[++top_n] = 0 - temp;
                // 处理到非数字字符时,回退一个字符
                st--;    
            }
            // 处理减号 
            else
            {
                // 处理符号栈中优先级等于或高于 '-' 的运算符
                while (top_s >= 0 && (symbol_stack[top_s] == '+' || 
                        symbol_stack[top_s] == '-' || symbol_stack[top_s] == '*' ||
                        symbol_stack[top_s] == '/'))
                {
                    /* 注意先出栈的作为第二个值在表达式中求值 */ 
                    n2 = number_stack[top_n--];
                    n1 = number_stack[top_n--];
                    number_stack[++top_n] = compute(n1, n2, symbol_stack[top_s--]);
                }
                // 将减号入栈
                symbol_stack[++top_s] = '-';
            }
        }
        // 处理正数或加号
        if (*st == '+')
        {
            if (st == st_b || *(st - 1) == '(' || *(st - 1) == '[' || *(st - 1) == '{')
            {
                // 不做处理 
            }
            else
            {
                while (top_s >= 0 && (symbol_stack[top_s] == '+' ||
                        symbol_stack[top_s] == '-' || symbol_stack[top_s] == '*' ||
                        symbol_stack[top_s] == '/'))
                {
                    n2 = number_stack[top_n--];
                    n1 = number_stack[top_n--];
                    number_stack[++top_n] = compute(n1, n2, symbol_stack[top_s--]);
                }
                // 将加号入栈 
                symbol_stack[++top_s] = '+'; 
            } 
        }
        // 处理乘号
        if (*st == '*')
        {
            while (top_s >= 0 &&(symbol_stack[top_s] == '*' ||
                    symbol_stack[top_s] == '/'))
            {
                n2 = number_stack[top_n--];
                n1 = number_stack[top_n--];
                number_stack[++top_n] = compute(n1, n2, symbol_stack[top_s--]);
            }
            symbol_stack[++top_s] = '*';
        }
        // 处理除号
        if (*st == '/')
        {
            while (top_s >= 0 &&(symbol_stack[top_s] == '*' ||
                    symbol_stack[top_s] == '/'))
            {
                n2 = number_stack[top_n--];
                n1 = number_stack[top_n--];
                number_stack[++top_n] = compute(n1, n2, symbol_stack[top_s--]);
            }
            symbol_stack[++top_s] = '/';
        }
        // 处理 ) 括号
        if (*st == ')') 
        {
            // 遇到左括号之前不断计算并压栈
            while (symbol_stack[top_s] != '(')
            {
                n2 = number_stack[top_n--];
                n1 = number_stack[top_n--];
                number_stack[++top_n] = compute(n1, n2, symbol_stack[top_s--]);
            }
            // 遇到左括号,弹出栈
            top_s--; 
        }
        // 处理 ] 括号
        if (*st == ']') 
        {
            // 遇到左括号之前不断计算并压栈
            while (symbol_stack[top_s] != '[')
            {
                n2 = number_stack[top_n--];
                n1 = number_stack[top_n--];
                number_stack[++top_n] = compute(n1, n2, symbol_stack[top_s--]);
            }
            // 遇到左括号,弹出栈
            top_s--; 
        }
        // 处理 } 括号
        if (*st == '}') 
        {
            // 遇到左括号之前不断计算并压栈
            while (symbol_stack[top_s] != '{')
            {
                n2 = number_stack[top_n--];
                n1 = number_stack[top_n--];
                number_stack[++top_n] = compute(n1, n2, symbol_stack[top_s--]);
            }
            // 遇到左括号,弹出栈
            top_s--; 
        }
        st++;
    }
    // 如果符号栈非空
    while (top_s >= 0)
    {
        n2 = number_stack[top_n--];
        n1 = number_stack[top_n--];
        number_stack[++top_n] = compute(n1, n2, symbol_stack[top_s--]);
    }
    
    return *number_stack;
}

int compute(int num1, int num2, char symbol)
{
    switch (symbol)
    {
        case '+':
            return num1 + num2;
        case '-':
            return num1 - num2;
        case '*':
            return num1 * num2;
        case '/':
            return num1 / num2;
        default:
            return -1;
    }
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n'); 
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
} 

  • HJ51 输出单向链表中倒数第k个结点(链表,查找)

华为机试 108 题(C 语言解答)_第55张图片

输入:
8
1 2 3 4 5 6 7 8
4

输出:
5

示例代码:HJ51.c


#include 
#include 

struct ListNode {
    int m_nKey;
    struct ListNode * m_pNext;
};

typedef struct ListNode * List;

List find_k(List list, int k);

int main(void)
{
    int n;
    int i;
    List head = NULL, rail, pre;
    List key;
    int k;
    
    while (scanf("%d", &n) == 1)
    {
        for (i = 0; i < n; i++)
        {
            rail = (List) malloc(sizeof(struct ListNode));
            rail->m_pNext = NULL;
            scanf("%d", &rail->m_nKey);
            if (head == NULL)
            {
                head = rail;
                pre = head;
            }
            else
            {
                pre->m_pNext = rail;
                pre = rail;
            }    
        }
        scanf("%d", &k); 
        key = find_k(head, k);
        if (key)
            printf("%d\n", key->m_nKey);
        while (head)
        {
            key = head;
            head = head->m_pNext;
            free(key);
        }    
    }
        
    return 0;
}

List find_k(List list, int k)
{
    List fast, low;
    
    if (list == NULL)
        return NULL;
    fast = low = list;
    while (fast != NULL && k > 1)
    {
        fast = fast->m_pNext;
        k--;
    }
    if (fast == NULL)
        return NULL;
    while (fast->m_pNext)
    {
        low = low->m_pNext;
        fast = fast->m_pNext;
    }
    
    return low;
}

  • HJ52 计算字符串的编辑距离(字符串,动态规划)

华为机试 108 题(C 语言解答)_第56张图片

输入:
abcdefg
abcdef

输出:
1

示例代码:HJ52.c


#include 
#include 
#define LEN 1001

int min(int a, int b, int c);
void d_p(char * str1, char * str2);

int main(void)
{ 
    char str1[LEN],str2[LEN];

    while (scanf("%s%s", str1, str2) == 2)
        d_p(str1, str2);
        
    return 0;
}

int min(int a, int b, int c)
{
    a = (a < b) ? a : b;
    a = (a < c) ? a : c;
    
    return a;
}

void d_p(char * str1, char * str2)
{
    int i, j;
    int len1 = strlen(str1);
    int len2 = strlen(str2);
    int dp[len1 + 1][len2 + 1];
    
    dp[0][0] = 0;                      // 初始化,若两个字符都为空 
    for (i = 1; i< len1 + 1; i++)      // 初始化,若第 2 个字符串为空 
        dp[i][0] = i;
    for (i = 1; i< len2 + 1; i++)      // 初始化,若第 1 个字符串为空
        dp[0][i] = i;
    for (i = 1; i < len1 + 1; i++)     // 1 ~ len1 个字符 
    {
        for (j = 1; j < len2 + 1; j++) // 1 ~ len2 个字符 
        {
            /* 如果相等则不变 */ 
            if (str1[i - 1] == str2[j - 1])
                dp[i][j] = dp[i - 1][j - 1];
            else /* 三种情况:1.修改
                              2.第 2 个字符串增加 1 个字符或 第 1 个字符串删去 1 个字符
                              3.第 1 个字符串增加 1 个字符或 第 2 个字符串删去 1 个字符 */ 
                dp[i][j] = min(dp[i - 1][j - 1] + 1, dp[i][j - 1] + 1, dp[i - 1][j] + 1);
        }
    }

    printf("%d \n", dp[len1][len2]);
}

  • HJ53 杨辉三角的变形(基础数学,总结规律,指数级增长,不能硬算)

华为机试 108 题(C 语言解答)_第57张图片
华为机试 108 题(C 语言解答)_第58张图片

输入:4

输出:3

示例代码:HJ53.c


#include 

int main(void)
{
    int num;
    int pos;
    
    while (scanf("%d", &num) == 1)
    {
        if (num < 3)
            pos = -1;
        else if (num % 2 == 1)
            pos = 2;
        else if (num % 4 == 0)
            pos = 3;
        else if (num % 4 == 2)
            pos = 4;
        printf("%d", pos);
    }
    
    return 0;
}

  • HJ54 表达式求值(栈,表达式求值,该题与HJ50要求一致,但测试用例更加严格)

  • HJ55 挑7(穷举,基础数学)

华为机试 108 题(C 语言解答)_第59张图片

输入:20

输出:3

说明:
输入20,1到20之间有关的数字包括7,14,17共3个。 

示例代码:HJ55.c


#include 

void find_seven(int n);

int main(void)
{
    int num;
    
    while (scanf("%d", &num) == 1)
        find_seven(num);
        
    return 0;
}

void find_seven(int n)
{
    int i;
    int count = 0;
    
    for (i = 1; i <= n; i++)
    {
        /* 判断是否是 7 的倍数,个位是否含 7 ,10 位是否含7,百位、千位、万位是否含 7 */ 
        if (i % 7 == 0 || i % 10 == 7 || (i / 10) % 10 == 7 || (i / 100) % 10 == 7 ||
            (i / 1000) % 10 == 7)
            count++;
    }
    printf("%d\n", count);
}

  • HJ56 完全数计算(穷举)

华为机试 108 题(C 语言解答)_第60张图片

输入:1000

输出:3

示例代码:HJ56.c


#include 

int main(void)
{
    int num;
    int count = 0, total = 0;
    int i, j;
    
    scanf("%d", &num);
    for (i = 1; i <= num; i++)
    {
        for (j = 1; j <= i / 2; j++)
        {
            if (i % j == 0)
                total += j;    
        }
        if (total == i)
            count++;
        total = 0;
    }
    printf("%d", count);
    
    return 0;
}

  • HJ57 高精度整数加法(字符串,栈)

华为机试 108 题(C 语言解答)_第61张图片

输入:
9876543210
1234567890

输出:
11111111100

示例代码:HJ57.c


#include 
#include 
#define LEN 10001

int main(void)
{
    char st_1[LEN], st_2[LEN]; // 常量不能改变地址 
    int i, j;
    int len1, len2;
    int remain = 0, now;
    int stack[LEN];
    char s_temp[LEN];
    int i_temp;
    int top = -1;
    
    while (scanf("%s%s", st_1, st_2) == 2)
    {
        len1 = strlen(st_1);
        len2 = strlen(st_2);
        if (len1 < len2)   /* 使 len1 >= len2 */ 
        {
            strcpy(s_temp, st_1);
            strcpy(st_1, st_2);
            strcpy(st_2, s_temp);
            i_temp = len1;
            len1 = len2;
            len2 = i_temp;
        }
        for (i = len1 - 1, j = len2 - 1; i > -1; i--, j--)
        {
            if (j > -1)
                now = (st_1[i] - '0') + (st_2[j] - '0');
            else
                now = (st_1[i] - '0');
            if (now + remain < 10)
            {
                stack[++top] = now + remain;
                remain = 0;
            }
            else
            {
                stack[++top] = now + remain - 10 ;
                remain = 1;
            }
        }
        if (remain == 1)
            stack[++top] = 1;
        for (i = top; i >= 0; i--)
            printf("%d", stack[i]);
    }
    
    return 0;
}

  • HJ58 输入n个整数,输出其中最小的k个(基础数学)

华为机试 108 题(C 语言解答)_第62张图片

输入:
5 2
1 3 5 7 2

输出:
1 2

示例代码:HJ58.c


#include 

void get_n_s(int ar[], int n, int k);

int main(void)
{
    int n, k;
    int i;
    
    scanf("%d%d", &n, &k);
    int ar[n];
    for (i = 0; i < n; i++)
        scanf("%d", ar + i);
    get_n_s(ar, n, k);
    
    return 0;
}

void get_n_s(int ar[], int n, int k)
{
    int i, j;
    int temp;
    
    for (i = 0; i < k; i++)
    {
        for (j = i + 1; j < n; j++)
        {
            if (ar[i] > ar[j])
            {
                temp = ar[i];
                ar[i] = ar[j];
                ar[j] = temp;
            }
        }
    }    
    for (i = 0; i < k; i++)
        printf("%d ", ar[i]); 
}

  • HJ59 找出字符串中第一个只出现一次的字符(字符串)


输入:asdfasdfo

输出:o

示例代码:HJ59.c


#include 
#include 
#include 
#define LEN 1001
#define SIZE 256

int main(void)
{
    char ch;
    static int stat[SIZE];
    static char str[LEN];
    int len = 0;
    int find = 0;
    int i;
    
    while ((ch = getchar()) != '\n')
    {
        str[len++] = ch;
        stat[toascii(ch)]++;
    }
    /* 第一次出现的位置,而不是 ASCII码中第一次出现的位置 */ 
    for (i = 0; i < len; i++)
    {
        if (stat[toascii(str[i])] == 1)
        {
            putchar(str[i]);
            find = 1;
            break;
        }
    }
    if (!find)
        printf("-1");
    
    return 0;
}

  • HJ60 查找组成一个偶数最接近的两个素数

华为机试 108 题(C 语言解答)_第63张图片

输入:
20

输出:
7
13

示例代码:HJ60.c


#include 

int is_num(int n);

int main(void)
{
    int num;
    int i;
    
    scanf("%d", &num);
    for (i = 0; i < num / 2 - 2; i++)
    {
        if (is_num(num / 2 + i) && is_num(num / 2 - i))
            break;
    } 
        
    printf("%d\n%d\n", num / 2 - i, num / 2 + i);
    
    return 0;
}

int is_num(int n)
{
    int i;
    int count = 0;
    
    for (i = 2; i <= n; i++)
        if (n % i == 0)
            count++;
    if (count == 1)
        return count;
    
    return 0;
}

  • HJ61 放苹果(动态规划,递归)

华为机试 108 题(C 语言解答)_第64张图片

输入:
7 3

输出:
8

示例代码:HJ61.c


#include 

int get_count1(int m, int n);  // 方法一:DP 
int get_count2(int m, int n);  // 方法二:REVERSE 

int main(void)
{
    int apple, plate;
    
    scanf("%d%d", &apple, &plate);
    printf("%d", get_count2(apple, plate));
    
    return 0;
}

/* 方法一:使用动态规划算法 */
int get_count(int m, int n)
{
    int i, j;
    int dp[m + 1][n + 1];
    
    /* i 个苹果放在 j 个盘子中 */
    for (i = 0; i <= m; i++)
    {
        for (j = 1; j <= n; j++)
        {
            if (i == 0 || i == 1 || j == 1)
                dp[i][j] = 1;
            else if (i < j)
                /* 有多余的盘子,题目要求不能右重复的序列 */ 
                dp[i][j] = dp[i][i];
            else
                /* 两种方案:1. 至少有一个盘子没放苹果 
                             2. 所有盘子都至少有一个苹果 */ 
                dp[i][j] = dp[i][j - 1] + dp[i - j][j]; 
        }
    }
            
    return dp[m][n];
}

/* 方法二:使用递归算法 */
int get_count2(int m, int n)
{
    if (m == 0 || m == 1 || n == 1)
        return 1;
    if (m < n)
        return get_count2(m, m);
    else
        return get_count2(m, n - 1) + get_count2(m - n, n);
}

  • HJ62 查找输入整数二进制中1的个数(位运算)

华为机试 108 题(C 语言解答)_第65张图片

输入:5

输出:2

说明:5 的二进制表示是 101,有 2 个 1   

示例代码:HJ62.c


#include 

int get_binary(int n);

int main(void)
{
    int num;
    
    while (scanf("%d", &num) == 1)
        printf("%d\n", get_binary(num));
    
    return 0;
}

int get_binary(int n)
{
    int count = 0;
    
    while (n)
    {
        count += (n & 1);
        n >>= 1;
    }
    
    return count;
}

  • HJ63 DNA序列(字符串)

华为机试 108 题(C 语言解答)_第66张图片

输入:
ACGT
2

输出:
CG

说明:
ACGT长度为2的子串有AC,CG,GT3个,其中AC和GT2个的GC-Ratio都为0.5,CG为1,故输出CG   

#include 
#include 
#define LEN 1001

int main(void)
{
    char str[LEN];
    int len;
    int size;
    int i, j;
    int max = 0;
    int count = 0;
    int id = 0;
    
    scanf("%s", str);
    scanf("%d", &size);
    len = (int) strlen(str);
    for (i = 0; i < len - size + 1; i++)
    {
        for (j = i; j < i + size; j++)
        {
            if(str[j] == 'G' || str[j] == 'C')
                count++;
        }
        if (count > max)
        {
            max = count;
            id = i;
        }
        count = 0;        
    }
    for (i = 0; i < size; i++)
        putchar(*(str + id + i));
        
    return 0;
}

  • HJ64 MP3光标位置(字符串)

华为机试 108 题(C 语言解答)_第67张图片
华为机试 108 题(C 语言解答)_第68张图片

输入:
10
UUUU

输出:
7 8 9 10
7

示例代码:HJ64.c


#include 
#include 

void show_mus(int pos, int value, int n);

int main(void)
{
    int n;
    int i;
    int * ar;
    char ch;
    int stat = 0; // 初始位置 
    int stat_value;
    
    while (scanf("%d", &n) == 1)
    {
        ar = (int *) malloc(sizeof(int) * n);
        for (i = 0; i < n; i++)
            ar[i] = i + 1;
        getchar();
        stat_value = ar[0];
        while ((ch = getchar()) != '\n') 
        {
            switch (ch)
            {
                case 'U':
                    if (stat_value == ar[0])
                    {
                        if (n <= 4)
                            stat = n - 1;    
                        else
                            stat = 3;
                        stat_value = ar[n - 1];
                    }    
                    else
                    {
                        stat--;
                        if (stat < 0)
                            stat = 0;
                        stat_value--;
                    }
                    break;
                case 'D':
                    if (stat_value == ar[n - 1])
                    {
                        stat = 0;
                        stat_value = ar[0];
                    }
                    else
                    {
                        stat++;
                        if (stat > 3)
                            stat = 3;
                        stat_value++;
                    }
                    break;
                    default : 
                        puts("Error!\n");    
            }
        }
        show_mus(stat, stat_value, n);
        
    }
    free(ar);
    
    return 0;    
}

void show_mus(int pos, int value, int n)
{
    int i;
    
    switch (pos)
    {
        case 0:
            for (i = 0; i < 4 && value + i <= n; i++)
                printf("%d ", value + i);
            break;
        case 1:
            printf("%d ", value - 1);
            for (i = 0; i < 3 && value + i <= n; i++)
                printf("%d ", value + i);
            break;
        case 2:
            printf("%d %d ", value - 2, value - 1);
            for (i = 0; i < 2 && value + i <= n; i++)
                printf("%d ", value + i);
            break;
        case 3:
            printf("%d %d %d ", value - 3, value - 2, value - 1);
            for (i = 0; i < 1 && value + i <= n; i++)
                printf("%d ", value + i);
            break;    
    }
    printf("\n%d\n", value);
}

  • HJ65 查找两个字符串a,b中的最长公共子串(字符串)

华为机试 108 题(C 语言解答)_第69张图片

输入:
abcdefghijklmnop
abcsafjklmnopqrstuvw

输出:
jklmnop

示例代码 1:HJ65.c


#include 
#include 
#include 
#define LEN 1001

char * s_gets(char * st, int n);
void cut_str(char * dest, char * start, char * end);
bool is_include(char * st_1, char * st_2);
void get_max(char * st_1, char * st_2, char * target);

int main(void)
{
    char st_1[LEN];
    char st_2[LEN];
    char target[LEN];
    
    while (s_gets(st_1, LEN) != NULL && s_gets(st_2, LEN) != NULL && 
            *st_1 != '\0' && *st_2 != '\0')
    {
        get_max(st_1, st_2, target);
        printf("%s\n", target);
    }
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

void cut_str(char * dest, char * start, char * end)
{
    int i;
    
    for (i = 0; i <= end - start; i++)
        dest[i] = *(start + i);
    dest[i] = '\0';
}

bool is_include(char * st_1, char * st_2)
{
    int i, j;
    int len_1 = strlen(st_1);
    int len_2 = strlen(st_2);
    int count = 0;
    
    for (i = 0; i < len_1; i++)
    {
        for (j = count; j < len_2; j++)
        {
            if (st_2[j] == st_1[i])
            {
                count++;
                if (count == len_2)
                    return true;
                break;
            }
            else
            {
                if (count > 0)
                {
                    i-= count;
                    count = 0;
                }
                break;
            }
        }
    }
    
    return false;    
}

void get_max(char * st_1, char * st_2, char * target)
{
    char dest[LEN];
    int len_1 = strlen(st_1);
    int len_2 = strlen(st_2);
    int i, j;
    int time;
    char s_temp[LEN];

    if (len_1 < len_2)
    {
        strcpy(s_temp, st_1);
        strcpy(st_1, st_2);
        strcpy(st_2, s_temp);
        len_1 = strlen(st_1);
        len_2 = strlen(st_2);
    }
    for (i = len_2; i >= 1; i--)
    {
        time = len_2 - i + 1;
        for (j = 0; j < time; j++)
        {
            cut_str(dest, st_2 + j, st_2 + i + j - 1);
            if (is_include(st_1, dest))
            {
                strcpy(target, dest);
                return;
            }    
        }
    }
}

示例代码 2,HJ65.c


#include 
#include 
#define LEN 1001

int main(void)
{
    char str1[LEN];
    char str2[LEN];
    char s_temp[LEN];
    char * s_max;
    int max;
    int len1, len2;
    int count;
    int i, j;
    
    /* 注意是在较短字符串中先出现,因此将较短字符串作为第一层循环 */ 
    while (scanf("%s%s", str1, str2) != EOF)
    {
        max = 0;
        len1 = strlen(str1);
        len2 = strlen(str2);
        if (len1 > len2)
        {
            strcpy(s_temp, str1);
            strcpy(str1, str2);
            strcpy(str2, s_temp);
            len1 = strlen(str1);
            len2 = strlen(str2);
        }
        for (i = 0; i < len1; i++)
        {
            for (j = 0; j < len2; j++)
            {
                count = 0;
                while (str1[i + count] == str2[j + count] && str1[i + count] != '\0')
                    count++;
                if (count > max)
                {
                    max = count;
                    s_max = str1 + i;
                }
            }
        }
        if (max)
        {
            for (i = 0; i < max; i++)
                putchar(*(s_max + i));
        }
    }
    
    return 0;
}

  • HJ66 配置文件恢复

华为机试 108 题(C 语言解答)_第70张图片
华为机试 108 题(C 语言解答)_第71张图片

输入:
reset
reset board
board add
board delet
reboot backplane
backplane abort

输出:
reset what
board fault
where to add
no board at all
impossible
install first

示例代码:HJ66.c


#include 
#include 
#include 
#define LEN 21
#define N 2

typedef struct {
    char order[N][LEN];
} Order;

int main(void)
{
    char input[LEN];
    Order com[6] = { { {"reset", ""} }, { {"reset", "board"} }, { {"board", "add"} },
        { {"board", "delete"} }, { {"reboot", "backplane"} }, { {"backplane", "abort"} } };
    char respond[7][LEN] = { "reset what", "board fault", "where to add", "no board at all",
        "impossible", "install first", "unknown command" };
    int order_words = 0;
    int order_match = 0;
    int i;
    char * order_1;
    char * order_2;
    int len1, len2; 
    int pre;
    char ch1, ch2;
    char * temp;
    
    while (fgets(input, LEN, stdin) != NULL && *input != '\n')
    {
        if ((temp = strchr(input, '\n')))
            *temp = '\0';
        order_words = strchr(input, ' ') == NULL ? 1 : 2;
        if (order_words == 1)
        {
            len1 = strlen(input);
            if (len1 <= (int) strlen(com[0].order[0]))
            {
                ch1 = *(com[0].order[0] + len1);
                *(com[0].order[0] + len1) = '\0';
                if (strstr(com[0].order[0], input))
                {
                    order_match = 1;
                    pre = 0;
                }
                *(com[0].order[0] + len1) = ch1;    
            }
        }
        else
        {
            order_1 = strtok(input, " ");
            order_2 = strtok(NULL, " ");
            len1 = strlen(order_1);
            len2 = strlen(order_2);
            for (i = 1; i < 6; i++)
            {
                if (len1 <= (int) strlen(com[i].order[0]) && len2 <= (int) strlen(com[i].order[1]))
                {
                    ch1 = *(com[i].order[0] + len1);
                    ch2 = *(com[i].order[1] + len2);
                    *(com[i].order[0] + len1) = '\0';
                    *(com[i].order[1] + len2) = '\0';
                    if (strstr(com[i].order[0], order_1) && strstr(com[i].order[1], order_2))
                    {
                        order_match++;
                        pre = i;
                    }
                    *(com[i].order[0] + len1) = ch1;
                    *(com[i].order[1] + len2) = ch2;
                }        
            }
        }
        if (order_match == 1)
            puts(respond[pre]);
        else
            puts(respond[6]);
        order_match = 0;
    }
    
    return 0;
}

  • HJ67 24点游戏算法(DFS)

华为机试 108 题(C 语言解答)_第72张图片

输入:7 2 1 10

输出:true

示例代码:HJ67.c


#include 
#include 
#define LEN 4

bool DFS(float * ar, float f_num, bool * visa);

int main(void)
{
    float ar[LEN]; 
    bool visa[LEN] = { false };  // 初始化为未使用 
    bool find = false;
    int i;
    
    for(i = 0; i < LEN; i++)     // 读入数据
        scanf("%f", ar + i);
    for (i = 0; i < LEN; i++)
    {
        visa[i] = true;
        if (DFS(ar, ar[i], visa))
        {
            puts("true");
            find = true;
            break;
        }
        visa[i] = false;
    }
    if (!find)
        puts("false");
    
    return 0;
}

bool DFS(float * ar, float f_num, bool * visa)
{
    int i;
     
    if(f_num == 24)               // 递归出口 
        return true;
    for(i = 0; i < 4; i++) 
    {
        if(!visa[i])
        {
            visa[i] = true;       // 标记已访问, 注意由于题目并不要求,未考虑除 0 的情况 
            if(DFS(ar, f_num + ar[i], visa) || DFS(ar, f_num - ar[i], visa)
                || DFS(ar, f_num * ar[i], visa) || DFS(ar, f_num / ar[i], visa))
                return true;
            visa[i] = false;      // 未找到则回退
        }
    }
    
    return false;            
}

  • HJ68 成绩排序

华为机试 108 题(C 语言解答)_第73张图片
华为机试 108 题(C 语言解答)_第74张图片

输入:
3
0
fang 90
yang 50
ning 70

输出:
fang 90
ning 70
yang 50

示例代码 1(不推荐):HJ68.c


#include 
#include 
#include 
#define SIZE 20

typedef struct {
    char name[SIZE];
    int score;
} Student;

typedef Student * Ps;

void sort(Ps student, int n, int choose);
void show(Ps student, Ps b_student, int n, int choose);

int main(void)
{
    int n;
    int choose;
    Ps student;
    Ps b_student; 
    int i;
    
    while (scanf("%d%d", &n, &choose) != EOF)
    {
        student = (Ps) malloc(sizeof(Student) * n);
        b_student = (Ps) malloc(sizeof(Student) * n);
        for (i = 0; i < n; i++)
        {
            scanf("%s", (student + i)->name);
            scanf("%d", &(student + i)->score);
            strcpy((b_student + i)->name, (student + i)->name);
            (b_student + i)->score = (student + i)->score;
        }
        sort(student, n, choose);
        show(student, b_student, n, choose);
    }
    free(student);
    free(b_student);
    
    return 0;
}

void sort(Ps student, int n, int choose)
{
    char s_temp[SIZE];
    int i_temp;
    int i, j;
    
    for (i = 0; i < n - 1; i++)
    {
        for (j = i + 1; j < n; j++)
        {
            if (choose == 0)
            {
                if ((student + i)->score < (student + j)->score)
                {
                    i_temp = (student + i)->score;
                    (student + i)->score = (student + j)->score;
                    (student + j)->score = i_temp;
                    strcpy(s_temp, (student + i)->name);
                    strcpy((student + i)->name, (student + j)->name);
                    strcpy((student +j)->name, s_temp);
                }    
            }
            else if (choose == 1)
            {
                if ((student + i)->score > (student + j)->score)
                {
                    i_temp = (student + i)->score;
                    (student + i)->score = (student + j)->score;
                    (student + j)->score = i_temp;
                    strcpy(s_temp, (student + i)->name);
                    strcpy((student + i)->name, (student + j)->name);
                    strcpy((student +j)->name, s_temp);
                }
            }
        }
    } 
}

void show(Ps student, Ps b_student, int n, int choose)
{
    int i, j;
    int count = 0;
    int pre = 100;
    int pre2 = 0; 
    int s_count;
    
    /* 从小到小 */ 
    if (choose == 0)
    {
        for (i = 0; i < n; i++)
        {
            if (i < n - 1)
            {
                if ((student + i)->score > (student + i + 1)->score && (student + i)->score < pre)
                {
                    pre = (student + i)->score;
                    printf("%s %d\n", (student + i)->name, (student + i)->score);
                    count = 0;
                }
                else
                {
                    if ((student + i)->score != pre)
                        count = 0;
                    count++;
                    s_count = 0;
                    for (j = 0; j < n; j++)
                    {
                        if ((student + i)->score == (b_student + j)->score)
                            s_count++;
                        if (s_count == count)
                        {
                            printf("%s %d\n", (b_student + j)->name, (b_student + j)->score);
                            pre = (b_student + j)->score;
                            break;    
                        }    
                    }
                }
            }
            else
            {
                if ((student + i)->score < pre)
                    count = 0;
                if (count == 0)
                    printf("%s %d\n", (student + i)->name, (student + i)->score);
                else
                {
                    s_count = 0;
                    for (j = 0; j < n; j++)
                    {
                        if ((student + i)->score == (b_student + j)->score)
                            s_count++;
                        if (s_count == count + 1)
                        {
                            printf("%s %d\n", (b_student + j)->name, (b_student + j)->score);
                            break;    
                        }    
                    }
                }
            }    
        }
    }
    /* 从小到大 */ 
    if (choose == 1)
    {
        for (i = 0; i < n; i++)
        {
            if (i < n - 1)
            {
                if ((student + i)->score < (student + i + 1)->score && (student + i)->score > pre2)
                {
                    pre2 = (student + i)->score;
                    printf("%s %d\n", (student + i)->name, (student + i)->score);
                    count = 0;
                }
                else
                {
                    if ((student + i)->score != pre2)
                        count = 0;
                    count++;
                    s_count = 0;
                    for (j = 0; j < n; j++)
                    {
                        if ((student + i)->score == (b_student + j)->score)
                            s_count++;
                        if (s_count == count)
                        {
                            printf("%s %d\n", (b_student + j)->name, (b_student + j)->score);
                            pre2 = (b_student + j)->score;
                            break;    
                        }    
                    }
                }
            }
            else
            {
                if ((student + i)->score > pre2)
                    count = 0;
                if (count == 0)
                    printf("%s %d\n", (student + i)->name, (student + i)->score);
                else
                {
                    s_count = 0;
                    for (j = 0; j < n; j++)
                    {
                        if ((student + i)->score == (b_student + j)->score)
                            s_count++;
                        if (s_count == count + 1)
                        {
                            printf("%s %d\n", (b_student + j)->name, (b_student + j)->score);
                            break;    
                        }    
                    }
                }
            }    
        }
    }
    
}

示例代码 2:HJ68.c


#include 
#include 
#define SIZE 20

typedef struct {
    char name[SIZE];
    int score;
    int id;
} Student;

typedef Student * Pst;

int BSCompare(const void * p1, const void * p2);
int SBCompare(const void * p1, const void * p2);
void showInfo(Student * student, int n);

int main(void)
{
    int n;         // 学生数量
    int choose;    // 排序方式
    Pst student;   // 存储学生信息
    int i;
    
    while (scanf("%d%d", &n, &choose) != EOF)
    {
        student = (Pst) malloc(sizeof(Student) * n);
        for (i = 0; i < n; i++)
        {
            scanf("%s", (student + i)->name);
            scanf("%d", &(student + i)->score);
            (student + i)->id = i;
        }
        if (choose == 0)
            qsort(student, n, sizeof(Student), BSCompare);
        if (choose == 1)
            qsort(student, n, sizeof(Student), SBCompare);
        showInfo(student, n); 
    }
    free(student);
    
    return 0;
}

int BSCompare(const void * p1, const void * p2)
{
    const Pst ps1 = (Pst) p1;
    const Pst ps2 = (Pst) p2;
    
    if (ps1->score != ps2->score)
        return ps2->score - ps1->score;
    else
        return ps1->id - ps2->id;
}

/* 如果返回负数,则 p1 所指排在左边 */ 
int SBCompare(const void * p1, const void * p2)
{
    const Pst ps1 = (Pst) p1;
    const Pst ps2 = (Pst) p2;
    
    if (ps1->score != ps2->score)
        return ps1->score - ps2->score;
    else
        return ps1->id - ps2->id;
}

void showInfo(Student * student, int n)
{
    int i;
    
    for (i = 0; i < n; i++)
        printf("%s %d\n", (student + i)->name, (student + i)->score);
}

  • HJ69 矩阵乘法(基础数学,线性代数,矩阵)

华为机试 108 题(C 语言解答)_第75张图片

输入:
2
3
2
1 2 3
3 2 1
1 2
2 1
3 3

输出:
14 13
10 11

示例代码:HJ69.c


#include 

void get_matrix(int row, int col, int m[][col]);
void matrix_mult(int m, int n, int s, int a[][n], int b[][s], int c[][s]);
void show_matrix(int row, int col, int m[][col]);

int main(void)
{
    int m, n, s;                       // m x n * n x s = m x s
    
    scanf("%d%d%d", &m, &n, &s);
    int a[m][n], b[n][s], c[m][s];
    get_matrix(m, n, a);
    get_matrix(n, s, b);
    matrix_mult(m, n, s, a, b, c);
    show_matrix(m, s, c);
    
    return 0;
}

void get_matrix(int row, int col, int m[][col])
{
    int i, j;
    
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
            scanf("%d", *(m + i) + j);
    }    
}

void matrix_mult(int m, int n, int s, int a[][n], int b[][s], int c[][s])
{
    int i, j, index;
    int sum;
    
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < s; j++)
        {
            sum = 0;
            for (index = 0; index < n; index++)
                sum += a[i][index] * b[index][j];
            c[i][j] = sum;
        }
    }
}

void show_matrix(int row, int col, int m[][col])
{
    int i, j;
    
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
            printf("%d ", m[i][j]);
        putchar('\n');
    }
}

  • HJ70 矩阵乘法计算量估算(基础数学,线性代数,矩阵)

华为机试 108 题(C 语言解答)_第76张图片

输入:
3
50 10
10 20
20 5
(A(BC))

输出:
3500

示例代码:HJ70.c


#include 
#include 
#include 
#define LEN 1001
#define N 2 

int get_num(int m, int n, int s);
int get_total(int arr[][N], char * st);

int main(void)
{
    int lists;
    int i;
    char str[LEN];
    
    scanf("%d", &lists);
    int arr[lists][N];
    for (i = 0; i < lists; i++)
        scanf("%d%d", *(arr + i), *(arr + i) + 1);
    scanf("%s", str);
    printf("%d", get_total(arr, str));
    
    return 0;
}

int get_num(int m, int n, int s)
{
    return m * n * s; 
}

int get_total(int arr[][N], char * st)
{
    int number_stack[LEN];
    int top_n = -1;
    int count = 0;
    int total = 0;
    int m, s;
    while (*st)
    {
        if (isupper(*st))
        {
            number_stack[++top_n] = count;
            count++;
        }
        if (*st == ')')
        {
            m = number_stack[top_n--];
            s = number_stack[top_n];
            total += get_num(arr[m][0], arr[m][1], arr[s][0]);
            arr[s][1] = arr[m][1];
        }
        st++;
    }
    
    return total;
}

  • HJ71 字符串通配符(字符串)

华为机试 108 题(C 语言解答)_第77张图片

输入:
te?t*.*
txt12.xls

输出:
false

示例代码:HJ71.c


#include 
#include 
#include 
#include 
#define LEN 101
 
bool judge(char * st_t, char * st_s);
 
int main(void)
{
    char st_t[LEN];
    char st_s[LEN];
     
    while (scanf("%s%s", st_t, st_s) == 2)
        printf("%s\n", judge(st_t, st_s) ? "true" : "false");
     
    return 0;
}

/* 重点是消耗完待匹配字符串后也要消耗完通配符 */ 
bool judge(char * st_t, char * st_s)
{
    bool in_supper = false;
    char * t_b, * s_b;
     
    while (*st_s)
    {
        if (*st_t == '*')
        {
            t_b = st_t;
            st_t++;
            in_supper = true;
            s_b = st_s;  
        }
        else if(tolower(*st_s) == tolower(*st_t) || (*st_t == '?' && (isalpha(*st_s) || isdigit(*st_s))))
        {
            st_t++;
            st_s++;
        }
        else if (in_supper)
        {
            st_s = s_b + 1;
            st_t = t_b;
        }
        else
            return false;
    }
    while (*st_t == '*' && *st_t != '\0')
        st_t++;
    if (!*st_t)
        return true;
     
    return false;
}

  • HJ72 百钱买百鸡问题(基础数学)

华为机试 108 题(C 语言解答)_第78张图片

输入:
1

输出:
0 25 75
4 18 78
8 11 81
12 4 84

示例代码:HJ72.c


#include 
#define CHIKEN_M 5
#define CHIKEN_F 3
#define CHIKEN_S (1 / 3)

int main(void)
{
    int num, n1, n2, n3;
    
    scanf("%d", &num);
    for (n1 = 0; n1 <= 20; n1++)
    {
        for (n2 = 0; n2 <= (100 - n1 * CHIKEN_M) / CHIKEN_F; n2++)
        {
            n3 = (100 - n1 * CHIKEN_M - n2 * CHIKEN_F) * 3;
            if ((n1 + n2 + n3) == 100)
                printf("%d %d %d\n", n1, n2, n3);
        }
    }
    
    return 0;
}

  • HJ73 计算日期到天数转换(基础数学)

华为机试 108 题(C 语言解答)_第79张图片

输入:2012 12 31

输出:366

示例代码:HJ73.c


#include 
#include 
#define MONTH 12

bool is_leap(int year);

int main(void)
{
    int year;
    int month;
    int day;
    int i;
    int days;
    int years[MONTH] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    
    while (scanf("%d%d%d", &year, &month, &day) == 3)
    {
        days = 0;
        if (month > 1)
        {
            if (is_leap(year))
                years[1] = 29;    
        }     
        for (i = 0; i < month - 1; i++)
            days += years[i];
        days += day;
        printf("%d\n", days);
        years[1] = 28;    
    }
    
    return 0;
}

bool is_leap(int year)
{
    return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0));
}

  • HJ74 参数解析(字符串)

华为机试 108 题(C 语言解答)_第80张图片

输入:
xcopy /s c:\\ d:\\e

输出:
4
xcopy
/s
c:\\
d:\\e

示例代码 1:HJ74.c


#include 
#include 
#include 
#include 
#define LEN 1001

char * s_gets(char * st, int n);
void get_info(char * st);
void print_n_st(char * st, int n);

int main(void)
{
    char str[LEN];
    
    while (s_gets(str, LEN) != NULL && *str != '\0')
        get_info(str);    
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

void get_info(char * st)
{
    bool in_com = false;
    int in_call = 0; 
    int count = 0;
    int stat[LEN][2];
    int len;
    char * st_b = st;
    int i;
    
    while (*st)
    {
        if (*st == '"')
        {
            in_call++;
        }    
        if (!isspace(*st) && in_com == false && *st != '"')
        {
            len = 1;
            in_com = true;
        }
        else if (!isspace(*st) && in_com == true && in_call != 2)
        {
            len++;
        }
        else if (isspace(*st) && in_call == 1)
            len++;
        if ((isspace(*st) && in_com == true && in_call == 0) || in_call == 2)
        {
            in_com = false;
            stat[count][0] = len;
            stat[count][1] = st - st_b - len;
            count++;
            in_call = 0;
        }
        st++;
    }
    if (in_com == true)
    {
        stat[count][0] = len;
        stat[count][1] = st - st_b - len;
        count++;
    }
    printf("%d\n", count);
    for (i = 0; i < count; i++)
    {
        print_n_st(st_b + stat[i][1], stat[i][0]);
    }
    
}

void print_n_st(char * st, int n)
{
    int i;
    
    for (i = 0; i < n; i++)
        putchar(*(st + i));
    putchar('\n');
}

示例代码 2:HJ74.c


#include 
#include 
#include 
#include 
#define LEN 1001

int main(void)
{
    int count, count2;
    char str[LEN];
    char * s_temp;
    int len;
    bool in;
    int i;
    
    while (fgets(str, LEN, stdin) != NULL && *str != '\n')
    {
        count = 0;
        count2 = 0;
        in = false;
        if ((s_temp = strchr(str, '\n')))
            *s_temp = '\0';
        else
            while (getchar() != '\n')
                continue;
        for (i = 0; i < (int) strlen(str); i++)
        {
            if (str[i] == '"' && in == false)
            {
                in = true;
                count2++;
                continue;    
            }    
            if (str[i] == '"' && in == true)
            {
                in = false;
                count2++;
                continue;
            }
            if (in == true)
                continue;
            if (isspace(str[i]))
                count++;
        }
        count += 1;
        printf("%d\n", count);
        len = strlen(str);
        strtok(str, "\"");
        for (i = 0; i < count2 - 1; i++)
            strtok(NULL, "\"");
        for (i = 0; i < len; i++)
        {
            if (!isspace(str[i]) && str[i] != '\0')
                putchar(str[i]);
            if (isspace(str[i]))
                putchar('\n');
            if (str[i] == '\0')
            {
                puts(str + i + 1);
                i += strlen(str + i + 1) + 2;
            }    
        }
    }
    
    return 0;
}

  • HJ75 公共子串计算(字符串)

华为机试 108 题(C 语言解答)_第81张图片

输入:
asdfas
werasdfaswer

输出:
6

示例代码 1:HJ75.c


#include 
#include 
#include 
#define LEN 151

char * s_gets(char * st, int n);
void cut_str(char * dest, char * start, char * end);
bool is_include(char * st_1, char * st_2);
int get_max(char * st_1, char * st_2);

int main(void)
{
    char st_1[LEN];
    char st_2[LEN];
    
    while (s_gets(st_1, LEN) != NULL && s_gets(st_2, LEN) != NULL && 
            *st_1 != '\0' && *st_2 != '\0')
    {
        printf("%d\n", get_max(st_1, st_2));
    }
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

void cut_str(char * dest, char * start, char * end)
{
    int i;
    
    for (i = 0; i <= end - start; i++)
        dest[i] = *(start + i);
    dest[i] = '\0';
}

bool is_include(char * st_1, char * st_2)
{
    int i, j;
    int len_1 = strlen(st_1);
    int len_2 = strlen(st_2);
    int count = 0;
    
    for (i = 0; i < len_1; i++)
    {
        for (j = count; j < len_2; j++)
        {
            if (st_2[j] == st_1[i])
            {
                count++;
                if (count == len_2)
                    return true;
                break;
            }
            else
            {
                if (count > 0)
                {
                    i-= count;
                    count = 0;
                }
                break;
            }
        }
    }
    
    return false;    
}

int get_max(char * st_1, char * st_2)
{
    char dest[LEN];
    int len_1 = strlen(st_1);
    int len_2 = strlen(st_2);
    int i, j;
    int time;
    
    if (len_1 > len_2)
    {
        for (i = len_2; i >= 1; i--)
        {
            time = len_2 - i + 1;
            for (j = 0; j < time; j++)
            {
                cut_str(dest, st_2 + j, st_2 + i + j - 1);
                if (is_include(st_1, dest))
                    return i;
            }
        }
    }
    else
    {
        for (i = len_1; i >= 1; i--)
        {
            time = len_1 - i + 1;
            for (j = 0; j < time; j++)
            {
                cut_str(dest, st_1 + j, st_1 + i + j - 1);
                if (is_include(st_2, dest))
                    return i;
            }
        }
    }
    
    return 0;
}

示例代码 2:HJ75.c


#include 
#include 
#include 
#define LEN 151

char * s_gets(char * st, int n);
void cut_str(char * dest, char * start, char * end);
int get_max(char * st_1, char * st_2);

int main(void)
{
    char st_1[LEN];
    char st_2[LEN];
    
    while (s_gets(st_1, LEN) != NULL && s_gets(st_2, LEN) != NULL && 
            *st_1 != '\0' && *st_2 != '\0')
    {
        printf("%d\n", get_max(st_1, st_2));
    }
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

void cut_str(char * dest, char * start, char * end)
{
    int i;
    
    for (i = 0; i <= end - start; i++)
        dest[i] = *(start + i);
    dest[i] = '\0';
}

int get_max(char * st_1, char * st_2)
{
    char dest[LEN];
    int len_1 = strlen(st_1);
    int len_2 = strlen(st_2);
    int i_temp;
    char s_temp[LEN];
    int i, j;
    int time;
    
    if (len_1 < len_2)
    {
        strcpy(s_temp, st_1);
        strcpy(st_1, st_2);
        strcpy(st_2, s_temp);
        i_temp = len_1;
        len_1 = len_2;
        len_2 = i_temp;
    }
    for (i = len_2; i >= 1; i--)
    {
        time = len_2 - i + 1;
        for (j = 0; j < time; j++)
        {
            cut_str(dest, st_2 + j, st_2 + i + j - 1);
            if (strstr(st_1, dest))
                return i;
        }
    }
    
    return 0;
}

示例代码 3:HJ75.c


#include 
#include 
#define LEN 151

int main(void)
{
    char str1[LEN];
    char str2[LEN];
    int i, j;
    int len1, len2;
    char s_temp[LEN];
    int i_temp;
    int max;
    int count;
    
    while (scanf("%s%s", str1, str2) != EOF)
    {
        max = 0;
        len1 = strlen(str1);
        len2 = strlen(str2);
        if (len1 < len2)
        {
            strcpy(s_temp, str1);
            strcpy(str1, str2);
            strcpy(str2, s_temp);
            i_temp = len1;
            len1 = len2;
            len2 = i_temp;
        }
        for (i = 0; i < len1; i++)
        {
            for (j = 0; j < len2; j++)
            {
                count = 0;
                while (str1[i + count] == str2[j + count] && str1[i + count] != '\0')
                    count++;
                if (count > max)
                    max = count;
            }
        }
        printf("%d", max);
    }
    
    return 0;
}

  • HJ76 尼科彻斯定理(基础数学)

华为机试 108 题(C 语言解答)_第82张图片

输入:6

输出:31+33+35+37+39+41

示例代码:HJ76.c


#include 
#include 
#define LEN 1001
#define SIZE 10 // 至少容纳 100 的 3 次方 

void get_str(int n);

int main(void)
{
    int num;
    
    scanf("%d", &num);
    get_str(num);
    
    return 0;
} 

void get_str(int n)
{
    int i;
    static char num[SIZE];
    static char notation[LEN];
    int start;
    
    if (n % 2 == 0)
        start = n * n - 1 - (n / 2 - 1) * 2;
    else
        start = n * n - (n / 2) * 2; 
    for (i = 0; i < n; i++)
    {
        sprintf(num, "%d", start);
        strcpy(notation + strlen(notation), num);
        start += 2;
        if (i != n - 1)
            strcpy(notation + strlen(notation), "+");
    }
    puts(notation);
}

  • HJ77 火车进站(栈,DFS)

华为机试 108 题(C 语言解答)_第83张图片

输入:
3
1 2 3

输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 2 1

说明:
第一种方案:1进、1出、2进、2出、3进、3出
第二种方案:1进、1出、2进、3进、3出、2出
第三种方案:1进、2进、2出、1出、3进、3出
第四种方案:1进、2进、2出、3进、3出、1出
第五种方案:1进、2进、3进、3出、2出、1出
请注意,[3,1,2]这个序列是不可能实现的。  

示例代码:HJ77.c


#include 
#include 
#include 
#include  
#define MAX 10000
#define LEN 10 

void DFS(int * train, int * station, int * out_station, int * kind, char (*res)[LEN], int top_sta, int top_out, int start, int n);
int SBCompare(const void * p1, const void * p2);

int main(void)
{
	int n;               // n 辆火车 
	int * train;         // 保存火车的编号 
	int * station;       // 保存火车站的火车 
	int * out_station;   // 保存出站的火车
	int kind;            // 合理的方案数
	char res[MAX][LEN];  // 保存合理的方案 
	int i, j;
	
	while (scanf("%d", &n) != EOF)
	{
		kind = 0; 
		train = (int *) malloc(sizeof(int) * n);
		station = (int *) malloc(sizeof(int) * n);
		out_station = (int *) malloc(sizeof(int) * n);
		for (i = 0; i < n; i++)
			scanf("%d", train + i);
		DFS(train, station, out_station, &kind, res, -1, -1, 0, n);
		qsort(res, kind, sizeof(res[0]), SBCompare);
		for (i = 0; i < kind; i++)
		{
			for (j = 0; j < n; j ++)
				printf("%c ", res[i][j]);
			putchar('\n');
		}	
	}
	free(train);
	free(station);
	free(out_station);
	
	return 0;
}

void DFS(int * train, int * station, int * out_station, int * kind, char (*res)[LEN], int top_sta, int top_out, int start, int n)
{
	int i;
	
	if (top_out + 1 == n)
	{
		for (i = 0; i < n; i++)
			res[*kind][i] = out_station[i] + '0';
		(*kind)++;
		
		return;
	}
	/* 可以选择是否入站 */ 
	if (start < n)
	{
		/* 选择入站 */ 
		station[++top_sta] = train[start++];
		DFS(train, station, out_station, kind, res, top_sta, top_out, start, n);
		/* 暂时不入站 */ 
		top_sta--;
		start--;
	}
	/* 可以选择是否出站 */ 
	if(top_sta >= 0)
	{
		/* 选择出站 */ 
		out_station[++top_out] = station[top_sta--];
		DFS(train, station, out_station, kind, res, top_sta, top_out, start, n);
		/* 暂时不出站 */ 
		station[++top_sta] = out_station[top_out--];
	} 
}

int SBCompare(const void * p1, const void * p2)
{
	return strcmp((char *) p1, (char *) p2);
}

  • HJ80 整型数组合并(排序)

华为机试 108 题(C 语言解答)_第84张图片

输入:
3
1 2 5
4
-1 0 3 2

输出:
-101235

示例代码 1:HJ80.c


#include 
#include 

void order_up(int ar[], int n);
void com_arr(int m, int n, int ar_a[], int ar_b[]);

int main(void)
{
    int m, n;
    int i;
    
    scanf("%d", &m);
    int ar_a[m];
    for (i = 0; i < m; i++)
        scanf("%d", ar_a + i);
    scanf("%d", &n);
    int ar_b[n];
    for (i = 0; i < n; i++)
        scanf("%d", ar_b + i);
    order_up(ar_a, m);
    order_up(ar_b, n);
    com_arr(m, n, ar_a, ar_b);
    
    return 0;
}

void order_up(int ar[], int n)
{
    int i, j;
    int temp;
    
    for (i = 0; i < n - 1; i++)
        for (j = i + 1; j < n; j++)
            if (ar[i] > ar[j])
            {
                temp = ar[i];
                ar[i] = ar[j];
                ar[j] = temp;
            }
}

void com_arr(int m, int n, int ar_a[], int ar_b[])
{
    int i, j;
    int temp = INT_MIN;
    
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++)
        {
            if (ar_b[j] < ar_a[i] && ar_b[j] > temp)
            {
                printf("%d", ar_b[j]);
                temp = ar_b[j];
            }
        }
        if (ar_a[i] > temp)
        {
            printf("%d", ar_a[i]);
            temp = ar_a[i];
        }
    }
    for (i = 0; i < n; i++)
    {
        if (ar_b[i] > temp)
            printf("%d", ar_b[i]);
    }    
}

示例代码 2:HJ80.c


#include 
#include 
#define LEN 1000

int SBCompare(const void * p1, const void * p2);

int main(void)
{
    int ar[LEN];
    int m, n;
    int i;
    
    while (scanf("%d", &m) == 1)
    {
        for (i = 0; i < m; i++)
            scanf("%d", ar + i);
        scanf("%d", &n);
        for (i = m; i < m + n; i++)
            scanf("%d", ar + i);
        qsort(ar, m + n, sizeof(int), SBCompare);
        for (i = 0; i < m + n; i++)
        {
            if (ar[i] != ar[i + 1])
                printf("%d", ar[i]);
        }
    }
    
    return 0;
}

int SBCompare(const void * p1, const void * p2)
{
    return *((int *) p1) - *((int *) p2);
}

  • HJ81 字符串字符匹配(字符串)

华为机试 108 题(C 语言解答)_第85张图片

输入:
bc
abc

输出:
true

说明:
其中abc含有bc,输出"true"

示例代码 1:HJ81.c


#include 
#include 
#include 
#define LEN 1001

char * s_gets(char * st, int n);
bool is_have(char * st1, char * st2);

int main(void)
{
    char str1[LEN], str2[LEN];
    
    while (s_gets(str1, LEN) != NULL && s_gets(str2, LEN) != NULL && *str1 != '\0' &&
            *str2 != '\0')
        if (is_have(str1, str2))
            printf("true\n");
        else
            printf("false\n");
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

bool is_have(char * st1, char * st2)
{
    int i, j;
    int len1 = strlen(st1); // short
    int len2 = strlen(st2); // long
    int count;
    
    for (i = 0; i < len1; i++)
    {
        count = 0;
        for (j = 0; j < len2; j++)
        {
            if (st2[j] == st1[i])
            {
                count++;
                break;
            }
        }
        if (!count)
            return false;    
    }
    
    return true;
}

示例代码 2:HJ81.c


#include 
#include 
#include 
#define LEN 201

int main(void)
{
    char str1[LEN];
    char str2[LEN];
    bool find;
    int i;
    
    while (scanf("%s%s", str1, str2) != EOF)
    {
        find = true;
        for (i = 0; i < (int) strlen(str1); i++)
        {
            if (!strchr(str2, str1[i]))
            {
                find = false;
                break;
            }
        }
        if (!find)
            puts("false");
        else
            puts("true");
    }
    
    return 0;
}

示例代码 3:HJ81.c


#include 
#include 
#include 
#define LEN 26

int main(void)
{
    static int str1[LEN];
    static int str2[LEN];
    bool find = true;
    char ch;
    int i;
    
    while ((ch = getchar()) != '\n')
        str1[ch - 'a'] = 1;
    while ((ch = getchar()) != '\n')
        str2[ch - 'a'] = 1;
    for (i = 0; i < LEN; i++)
    {
        if (str1[i] == 1 && str2[i] != 1)
            find = false;
    }
    if (find)
        puts("true");
    else
        puts("false");
        
    return 0;
}

  • HJ82 将真分数分解为埃及分数(基础数学)

华为机试 108 题(C 语言解答)_第86张图片

输入:
8/11
2/4

输出:
1/2+1/5+1/55+1/110
1/3+1/6

说明:
第二个样例直接输出1/2也是可以的    

示例代码 1:HJ82.c


#include 

void caculate(int a, int b);

int main(void)
{
    int a, b;
    
    while (scanf("%d/%d", &a, &b) == 2)
        caculate(a, b);
        
    return 0;
}

void caculate(int a, int b)
{
    if (a == 1)
    {
        printf("1/%d\n", b);
        return;
    }
    if (b % a == 0)
    {
        printf("1/%d\n", b / a);
        return;
    }
    printf("1/%d+", b / a + 1);
    caculate(a - b % a, b * (b / a + 1));
}

示例代码 2:HJ82.c


#include 

int gcd(int a, int b);

int main()
{
    int a, b;
    
    while (scanf("%d/%d", &a, &b) != EOF)
    {
        int under[b];
        int top = -1;
        int q, r, div;
        
        div = gcd(a, b);
        a /= div;
        b /= div;
        if (a == 1)
            under[++top] = b;
        else
        {
            while (a != 1) // b = a * q + r -> a + b = a * (q + 1) + r
            {               
                q = b / a;
                r = b % a;
                under[++top] = q + 1;
                a = a - r;
                b = b * (q + 1);
                div = gcd(a, b);
                a /= div;
                b /= div;
            }
            under[++top] = b;
        }

        for (int i = 0; i <= top; i++)
        {
            if (i != 0)
                printf("+");
            printf("1/%d", under[i]);
        }
        printf("\n");
  }
  
  return 0;
}

int gcd(int a, int b) // 最大公因数 
{
    int t;
    
    while (b != 0)
    {
        t = a % b;
        a = b;
        b = t;
    }
    
    return a;
}

  • HJ83 二维数组操作(数组)

华为机试 108 题(C 语言解答)_第87张图片
华为机试 108 题(C 语言解答)_第88张图片

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

输出:
0
-1
0
-1
0
0
-1
0
0
-1

说明:
本组样例共有2组样例输入。
第一组样例:
1.初始化数据表为4行9列,成功
2.交换第5行1列和第2行6列的数据,失败。因为行的范围应该是(0,3),不存在第5行。
3.在第0行上方添加一行,成功。
4.在第8列左边添加一列,失败。因为列的总数已经达到了9的上限。
5.查询第2行第3列的值,成功。
第二组样例:
1.初始化数据表为4行7列,成功
2.交换第4行2列和第3行2列的数据,失败。因为行的范围应该是(0,3),不存在第4行。
3.在第3行上方添加一行,成功。
4.在第3列左边添加一列,成功。
5.查询第4行7列的值,失败。因为虽然添加了一行一列,但数据表会在添加后恢复成4行7列的形态,所以行的区间仍然在[0,3],列的区间仍然在[0,6],无法查询到(4,7)坐标。  

示例代码:HJ83.c


#include 

int main(void)
{
    int m, n;
    int x1, y1, x2, y2;
    int x, y;
    
    while (scanf("%d%d", &m, &n) == 2)
    {
        if (m > 0 && m < 10 && n > 0 && n < 10)
            puts("0");
        else
        {
            puts("-1");
            return -1;
        }
        scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
        if (x1 >= 0 && x1 < m && y1 >= 0 && y1 < n 
            && x2 >= 0 && x2 < m && y2 >= 0 && y2 < n)
            puts("0");
        else
            puts("-1");
        scanf("%d", &x);
        if (x >= 0 && x < m && m < 9)
            puts("0");
        else
            puts("-1");
        scanf("%d", &y);
        if (y >= 0 && y < n && n < 9)
            puts("0");
        else
            puts("-1");
        scanf("%d%d", &x, &y);
        if (x >= 0 && x < m && y >= 0 && y < n)
            puts("0");
        else
            puts("-1");
    }
    
    return 0;
}

HJ84 统计大写字母个数(字符串)

华为机试 108 题(C 语言解答)_第89张图片

输入:A 1 0 1 1150175017(&^%&$vabovbaoadd 123#$%#%#O

输出:2

示例代码 1:HJ84.c


#include 
#include 
#include 
#define LEN 251

char * s_gets(char * st, int n);
int get_upper(char * st);

int main(void)
{
    char str[LEN];
    
    if (s_gets(str, LEN) != NULL && *str != '\0')
        printf("%d", get_upper(str));
        
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

int get_upper(char * st)
{
    int count = 0;
    
    while (*st)
    {
        if (isupper(*st))
            count++;
        st++;
    }
    
    return count;
}

示例代码 2:HJ84.c


#include 
#include 

int main(void)
{
    char ch;
    int count = 0;
    
    while ((ch = getchar()) != '\n')
    {
        if (isupper(ch))
            count++;
    }
    printf("%d", count);
    
    return 0;
}

HJ85 最长回文子串(字符串)

华为机试 108 题(C 语言解答)_第90张图片

输入:cdabbacc

输出:4

说明:abba为最长的回文子串   

示例代码:HJ85.c


#include
#include
#define LEN 351 

int main(void){
    char str[LEN];
    int max = 0;
    int i, j;
    int l, r;
    
    scanf("%s", str);
    for (i = 0; i < (int) strlen(str) - 1; i++) // 此处 i 是左端点
    {
        for (j = i + 1; j < (int) strlen(str); j++) // cdabbacc
        {
            l = i, r = j;
            while (l < r)
            {
                if (str[r] != str[l])
                    break;
                else
                {
                    l++;
                    r--;
                }
            }
            if (l >= r) // 包含 abcba 这种情况,最终停在同一位置 
                max = max > (j - i + 1) ? max : (j - i + 1);
        }
    }
    printf("%d", max);
    
    return 0;
}

  • HJ86 求最大连续bit数(位运算)

华为机试 108 题(C 语言解答)_第91张图片

输入:200

输出:2

说明:200的二进制表示是11001000,最多有2个连续的1。

示例代码:HJ86.c


#include 

int get_continue(int n);

int main(void)
{
    int num;
    
    while (scanf("%d", &num) == 1)
        printf("%d\n", get_continue(num));
        
    return 0;
}

int get_continue(int n)
{
    int pre = 0, curr = 0;
    
    while (n)
    {
        if (n & 1)
            curr++;
        else
        {
            if (curr > pre)
                pre = curr;
            curr = 0;
        }
        n >>= 1;
    }
    
    return pre > curr ? pre : curr;
}

  • HJ87 密码强度等级(字符串)

华为机试 108 题(C 语言解答)_第92张图片
华为机试 108 题(C 语言解答)_第93张图片
华为机试 108 题(C 语言解答)_第94张图片

输入:38$@NoNoN

输出:VERY_SECURE

说明:
样例的密码长度大于等于8个字符,得25分;
大小写字母都有所以得20分;
有两个数字,所以得20分;
包含大于1符号,所以得25分;
由于该密码包含大小写字母、数字和符号,所以奖励部分得5分;
经统计得该密码的密码强度为25+20+20+25+5=95分。

示例代码:HJ87.c


#include 
#include 
#include 
#define LEN 301 

char * s_gets(char * st, int n);
int get_score(char * st);

int main(void)
{
    char str[LEN];
    int score;
    char judge[7][12] = { "VERY_SECURE", "SECURE", "VERY_STRONG", "STRONG",
                            "AVERAGE", "WEAK", "VERY_WEAK" };
    
    if (s_gets(str, LEN) != NULL && *str != '\0')
        score = get_score(str);
    if (score >= 90)
        puts(judge[0]);
    else if (score >= 80)
        puts(judge[1]);
    else if (score >= 70)
        puts(judge[2]);
    else if (score >= 60)
        puts(judge[3]);
    else if (score >= 50)
        puts(judge[4]);
    else if (score >= 25)
        puts(judge[5]);
    else if (score >= 0)
        puts(judge[6]);
        
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

int get_score(char * st)
{
    int len = strlen(st);
    int low_alpha = 0, up_alpha = 0;
    int num_count = 0;
    int other = 0;
    int score = 0;
    
    while (*st)
    {
        if (islower(*st))
            low_alpha++;
        else if (isupper(*st))
            up_alpha++;
        else if (isdigit(*st))
            num_count++;
        else
            other++;
        st++;
    }
    if (len <= 4 && len > 0)
        score += 5;
    else if (len <= 7)
        score += 10;
    else
        score += 25;
    if (low_alpha == 0 && up_alpha == 0)
        score += 0;
    else if (low_alpha > 0 && up_alpha > 0)
        score += 20;
    else
        score += 10;
    if (num_count == 0)
        score += 0;
    else if (num_count == 1)
        score += 10;
    else
        score += 20;
    if (other == 0)
        score += 0;
    else if (other == 1)
        score += 10;
    else
        score += 25;
    if (low_alpha && up_alpha && num_count && other)
        score += 5;
    else if ((low_alpha || up_alpha) && num_count && other)
        score += 3;
    else if ((low_alpha || up_alpha) && num_count)
        score += 2;
        
    return score;    
}

  • HJ88 扑克牌大小

华为机试 108 题(C 语言解答)_第95张图片
华为机试 108 题(C 语言解答)_第96张图片

输入:4 4 4 4-joker JOKER

输出:joker JOKER

示例代码:HJ88.c


#include 
#include 
#include 
#include 
#define LEN 30

/* 1:Singel、2: Pair、3: Tripel、5: Sequence、 4:Bomb、8:SupterBomb */ 
int JudgeType(char * st);

int main(void)
{
    char puker[15][6] = { {"3"}, {"4"}, {"5"}, {"6"}, {"7"}, {"8"}, {"9"},
                          {"10"}, {"J"}, {"Q"}, {"K"}, {"A"}, {"2"}, 
                          {"joker"}, {"JOKER"} };
    static char puker1[LEN];
    static char puker1_b[LEN];
    static char puker2[LEN];
    static char puker2_b[LEN];
    int len1 = 0, len2 = 0;
    int type1, type2;
    int i_temp1, i_temp2;
    int i;
    char ch;
    
    while ((ch = getchar()) != '-')
        puker1[len1++] = ch;
    while((ch = getchar()) != '\n')
        puker2[len2++] = ch;
    strcpy(puker1_b, puker1);
    strcpy(puker2_b, puker2);
    /* puker1:Bomb、puker2:No Bomb */ 
    type1 = JudgeType(puker1);
    type2 = JudgeType(puker2);
    if (type1 % 4 == 0 && type2 % 4 != 0)
        puts(puker1);
    else if (type2 % 4 == 0 && type1 % 4 != 0)
        puts(puker2);
    else if (type1 == 8 && type2 == 4)
        puts(puker1);
    else if (type2 == 8 && type1 == 4)
        puts(puker2);
    else if (type1 == type2)
    {
        if (type1 != 1)
        {
            strtok(puker1, " ");
            strtok(puker2, " ");
        }
        for (i = 0; i < 15; i++)
        {
            if (strcmp(puker1, puker[i]) == 0)
                i_temp1 = i;
            if (strcmp(puker2, puker[i]) == 0)
                i_temp2 = i;
        }
        if (i_temp1 > i_temp2)
            puts(puker1_b);
        else if (i_temp1 < i_temp2)
            puts(puker2_b);
    }
    else
        puts("ERROR");
    
    return 0;        
}

int JudgeType(char * st)
{
    int type;
    int count = 0;
    int len = strlen(st);
    int i;
    
    for (i = 0; i < len; i++)
    {
        if (isspace(st[i]))
            count++;    
    }
    if (count == 0)
        type = 1;
    if (count == 2)
        type = 3;
    if (count == 3)
        type = 4;
    if (count == 4)
        type = 5;
    if (count == 1)
    {
        if (strstr(st, "joker"))
            type = 8;
        else
            type = 2;
    }
    
    return type;
}

  • HJ89 24点运算(基础数学,DFS)

华为机试 108 题(C 语言解答)_第97张图片
华为机试 108 题(C 语言解答)_第98张图片

输入:4 2 K A

输出:K-A*4/2

说明:A+K*2-4也是一种答案,输出任意一种即可    

示例代码:HJ89.c


#include 
#include 
#include 
#define LEN 20
#define SIZE 4

bool DFS(float * num, bool * used, char * symbol_stack, float * num_stack, int n_top, int s_top, float start);

int main(void)
{
    char puker[LEN];
    float num[SIZE];
    char symbol_stack[SIZE];
    float num_stack[SIZE];
    bool find;
    bool used[SIZE] = { false };
    int s_top, n_top;
    int i;
    
    while (fgets(puker, LEN, stdin) != NULL && *puker != '\0')
    {
        find = false;
        *(puker + (int) strlen(puker) - 1) = '\0';
        if (strstr(puker, "joker") || strstr(puker, "JOKER"))
        {
            puts("ERROR");
            break;
        }
        for (i = 0; i < 4; i++)
        {
            if (*(puker + 2 * i) == 'J')
                num[i] = 11;
            else if (*(puker + 2 * i) == 'Q')
                num[i] = 12;
            else if (*(puker + 2 * i) == 'K')
                num[i] = 13;
            else if (*(puker + 2 * i) == 'A')
                num[i] = 1;
            else
                num[i] = *(puker + 2 * i) - '0';
        }
        for (i = 0; i < SIZE; i++)
        {
            n_top = -1;
            s_top  = -1;
            used[i] = true;
            num_stack[++n_top] = num[i];
            if (DFS(num, used, symbol_stack, num_stack, n_top, s_top, num[i]))
            {
                find = true;
                break;
            }
            used[i] = false;
        }
        if (!find)
            puts("NONE");    
    }
    
    return 0;
}

bool DFS(float * num, bool * used, char * symbol_stack, float * num_stack, int n_top, int s_top, float start)
{
    int i;
    
    if (start == 24 && s_top == 2)
    {
        for (i = 0; i < SIZE; i++)
        {
            if (num_stack[i] == 11)
                putchar('J');
            else if (num_stack[i] == 12)
                putchar('Q');
            else if (num_stack[i] == 13)
                putchar('K');
            else if (num_stack[i] == 1)
                putchar('A');
            else
                printf("%.0f", num_stack[i]);
            if (i < SIZE - 1)
                printf("%c", symbol_stack[i]);
        }
        return true;
    }
    for (i = 0; i < SIZE; i++)
    {
        if (!used[i])
        {
            used[i] = true;
            symbol_stack[++s_top] = '+';
            num_stack[++n_top] = num[i];
            if (DFS(num, used, symbol_stack, num_stack, n_top, s_top, start + num[i]))
                return true;
            s_top--;
            n_top--;
            symbol_stack[++s_top] = '-';
            num_stack[++n_top] = num[i];
            if (DFS(num, used, symbol_stack, num_stack, n_top, s_top, start - num[i]))
                return true;
            s_top--;
            n_top--;
            symbol_stack[++s_top] = '*';
            num_stack[++n_top] = num[i];
            if (DFS(num, used, symbol_stack, num_stack, n_top, s_top, start * num[i]))
                return true;
            s_top--;
            n_top--;
            symbol_stack[++s_top] = '/';
            num_stack[++n_top] = num[i];
            if (DFS(num, used, symbol_stack, num_stack, n_top, s_top, start / num[i]))
                return true;
            s_top--;
            n_top--;
            used[i] = false;
        }
    }
    
    return false;
}

  • HJ90 合法IP(字符串)

华为机试 108 题(C 语言解答)_第99张图片

输入:255.255.255.1000

输出:NO

示例代码:HJ90.c


#include 
#include 
#include 
#define LEN 101

bool is_legal(char * st);

int main(void)
{
    char str[LEN];
    
    while (scanf("%s", str) == 1)
        printf("%s\n", is_legal(str) ? "YES" : "NO");
    
    return 0;
}

bool is_legal(char * st)
{
    char * st_b = st;
    int num_count = 0;
    int dot_count = 0;
    int num = 0;
    
    while (*st)
    {
        if ((st == st_b  && !(*st >= '0' && *st <= '9')) || (*st == '.' && !(*(st + 1) >= '0' && *(st + 1) <= '9')))
            return false;
        if (st == st_b && *st == '0' && isdigit(*(st + 1)))
            return false;
        if (*st == '.' && *(st + 1) == '0' && isdigit(*(st + 2)))
            return false;
        if (isdigit(*st))
        {
            num = 10 * num + *st - '0';
            if (!isdigit(*(st + 1)))
                num_count++;    
        }    
        if (*st == '.')
        {
            dot_count++;
            if (!(num >= 0 && num < 256))
                return false;    
            num = 0;
        }    
        st++;
    }
    if (!(num_count == 4 && dot_count == 3)  || !(num >= 0 && num < 256))
        return false;
    
    return true;
}

  • HJ91 走方格的方案数(动态规划)

华为机试 108 题(C 语言解答)_第100张图片

输入:2 2

输出:6

示例代码:HJ91.c


#include

int main(void)
{
    int m, n;

    if (scanf("%d%d", &m, &n) == 2)
    {
        int dp[m + 1][n + 1];
        for (int i = 0; i <= m; i++)
        {
            for (int j = 0; j <= n; j++)
            {
                /* 初始化初值,只有一条线,方案只有1种          */
                if (i == 0 || j == 0)
                    dp[i][j] = 1; 
                else
                /* 与上面一个格子,和左边一个格子的情况总和相同 */
                    dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }
        }

        printf("%d\n", dp[m][n]);
    }
    
    return 0;
}

  • HJ92 在字符串中找出连续最长的数字串(字符串)

华为机试 108 题(C 语言解答)_第101张图片

输入:
abcd12345ed125ss123058789
a8a72a6a5yy98y65ee1r2

输出:
123058789,9
729865,2

说明:
样例一最长的数字子串为123058789,长度为9
样例二最长的数字子串有72,98,65,长度都为2    

示例代码:HJ92.c


#include 
#include 
#include 
#include 
#define LEN 201

char * s_gets(char * st, int n);
void get_num(char * st);
void print(char * start, int n);

int main(void)
{
    char str[LEN];
    
    while (s_gets(str, LEN) != NULL && *str != '\0')
        get_num(str);
    
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

void get_num(char * st)
{
    int i;
    int mark[LEN][2];
    int max = 0;
    int count = 0;
    int lenth = 0;
    bool in_num = false;
    char * st_b = st;
    
    while (*st)
    {
        if (isdigit(*st) && in_num == false)
        {
            lenth = 1;
            if (lenth > max)
                max = lenth;
            in_num = true;
        }
        else if (isdigit(*st) && in_num == true)
        {
            lenth++;
            if (lenth > max)
                max = lenth;
        }
        if (!isdigit(*st) && in_num == true)
        {
            in_num = false;
            mark[count][0] = lenth;
            mark[count][1] = st - st_b;
            count++;
        }
        st++;
    }
    if (in_num == true)
    {
        mark[count][0] = lenth;
        mark[count][1] = st - st_b;
        count++;
    }
    for (i = 0; i < count; i++)
    {
        if (mark[i][0] == max)
            print(st_b + mark[i][1] - max, max);
    }    
    printf(",%d", max);
}

void print(char * start, int n)
{
    int i;
    
    for (i = 0; i < n; i++)
        putchar(*(start + i));
}

  • HJ93 数组分组(数组,DFS)

华为机试 108 题(C 语言解答)_第102张图片

输入:
4
1 5 -5 1

输出:
true

说明:
第一组:5 -5 1
第二组:1   

示例代码:HJ93.c


#include 
#include 
#include  
#define LEN 50

bool DFS(int * ar_o, int count_o, bool * used, int start, int total);

int main(void)
{
    int n;
    int ar[LEN];
    int ar_o[LEN];
    int count_o;
    int total;
    int total_3;
    int total_5;
    int total_o;
    bool used[LEN] = { false };
    int i;
    
    while (scanf("%d", &n) == 1)
    {
        count_o = 0;
        total = total_3 = total_5 = total_o = 0;
        for (i = 0; i < n; i++)
        {
            scanf("%d", ar + i);
            if (ar[i] % 3 == 0)
                total_3 += ar[i];    
            else if (ar[i] % 5 == 0)
                total_5 += ar[i];    
            else
            {
                ar_o[count_o++] = ar[i];
                total_o += ar[i];
            }    
            total += ar[i];
        }
        if (total % 2 != 0)
        {
            puts("false");
            continue;
        }
        if (total_3 == total_5 && total_o == 0)
        {
            puts("true");
            continue;
        }
        if (DFS(ar_o, count_o, used, total_3, total / 2))
            puts("true");
        else
            puts("false");
    }
    
    return 0;
}

bool DFS(int * ar_o, int count_o, bool * used, int start, int total)
{
    int i;
    
    if (start == total)
        return true;
    for (i = 0; i < count_o; i++)
    {
        if (!used[i])
        {
            used[i] = true;
            if (DFS(ar_o, count_o, used, start + ar_o[i], total))
                return true;
            used[i] = false;
        }
    }
    
    return false;
}

  • HJ94 记票统计(字符串)

华为机试 108 题(C 语言解答)_第103张图片

输入:
4
A B C D
8
A D E CF A GG A B

输出:
A : 3
B : 1
C : 0
D : 1
Invalid : 3

说明:
E CF GG三张票是无效的,所以Invalid的数量是3. 

示例代码:HJ94.c


#include 
#include 
#define LEN 21

void get_tollet(int m, int n, char ar[][LEN], char br[][LEN]);

int main(void)
{
    int m, n;
    int i;
    
    scanf("%d", &m);
    char ar[m][LEN];
    for (i = 0; i < m; i++)
        scanf("%s", ar[i]);;
    scanf("%d", &n);
    char br[n][LEN];
    for (i = 0; i < n; i++)
        scanf("%s", br[i]);
    get_tollet(m, n, ar, br);
    
    return 0;
}

void get_tollet(int m, int n, char ar[][LEN], char br[][LEN])
{
    int i, j;
    int stat[m];
    int use = 0;
    
    for (i = 0; i < m; i++)
        stat[i] = 0;
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < m; j++)
        {
            if (!strcmp(ar[j], br[i]))
            {
                stat[j]++;
                break;
            }
        }
    }            
    for (i = 0; i < m; i++)
    {
        printf("%s : %d\n", ar[i], stat[i]);
        use += stat[i];
    }
    printf("Invalid : %d\n", n - use);
}

  • HJ95 人民币转换(字符串)

华为机试 108 题(C 语言解答)_第104张图片

输入:151121.15

输出:人民币拾伍万壹仟壹佰贰拾壹元壹角伍分

示例代码:HJ95.c


#include 
#include 
#include 
#define LEN 50

void get_bits(double d_n, int * ar);
void printInfo(int n, char number[][LEN]);

int main(void)
{
    double d_n;
    static int ar[5];
    bool flag = false;
    char number[13][LEN] = { {"零"}, {"壹"}, {"贰"}, {"叁"}, {"肆"}, {"伍"}, {"陆"}, {"柒"},
                             {"捌"}, {"玖"}, {"拾"}, {"佰"}, {"仟"} };
    char unit[6][LEN] = { {"亿"}, {"万"}, {"元"}, {"角"}, {"分"}, {"整"} };
    
    while (scanf("%lf", &d_n) == 1)
    {
        get_bits(d_n, ar);
        if (ar[0] || ar[1] || ar[2] || ar[3] || ar[4])
            printf("人民币"); 
        if (ar[4])
        {
            printInfo(ar[4], number);
            printf("%s", unit[0]);
            flag = true;
        }
        if (ar[3])
        {
            if (flag && ar[4] % 10 == 0)
                printf("%s", number[0]);
            printInfo(ar[3], number);
            printf("%s", unit[1]);
            flag = true;
        }
        if (ar[2])
        {
            if (flag && ar[3] % 10 == 0)
                printf("%s", number[0]);
            printInfo(ar[2], number);
            flag = true;
        }
        if (flag)
            printf("%s", unit[2]);
        if (ar[1])
            printf("%s%s", number[ar[1]], unit[3]);
        if (ar[0])
            printf("%s%s", number[ar[0]], unit[4]);
        if (!ar[1] && !ar[0] && flag)
            printf("%s", unit[5]);
    }
    
    return 0;
}

void get_bits(double d_n, int * ar)
{
    /* 分 */
    double temp = d_n * 100;
    ar[0] = (long long) round(temp) % 10;
    /* 角 */
    ar[1] = ((long long) round(temp) / 10) % 10;
    /* 元 */
    ar[2] = (long long) d_n % 10000;
    /* 万 */
    ar[3] = ((long long) d_n / 10000) % 10000;
    /* 亿 */
    ar[4] = (long long) d_n / 100000000;
}

void printInfo(int n, char number[][LEN])
{
    bool flag = false;
    
    if (n >= 1000)
    {
        printf("%s%s", number[n / 1000], number[12]);
        n %= 1000;
        flag = true;
    }
    if (n < 100 && n >= 10 && flag)
    {
        printf("%s", number[0]);
    }
    else if (n >= 100)
    {
        printf("%s%s", number[n / 100], number[11]);
        n %= 100;
        flag = true;
    }
    if (n < 10 && n > 0 && flag)
    {
        printf("%s", number[0]);
    }
    else if (n >= 10)
    {
        if (n / 10 == 1)
            printf("%s", number[10]);
        else
            printf("%s%s", number[n / 10], number[10]);
        n %= 10;
    }
    if (n > 0)
        printf("%s", number[n]);
}

  • HJ96 表示数字(字符串)

华为机试 108 题(C 语言解答)_第105张图片

输入:Jkdi234klowe90a3

输出:Jkdi*234*klowe*90*a*3*

示例代码:HJ96.c


#include 
#include 
#include 

int main(void)
{
    int ch;
    bool in_num = false;
    
    while ((ch = getchar()) != '\n')
    {
        if (isdigit(ch) && !in_num)
        {
            putchar('*');
            putchar(ch);
            in_num = true;
        }
        else if (!isdigit(ch) && in_num)
        {
            putchar('*');
            putchar(ch);
            in_num = false;
        }
        else
            putchar(ch);
    }
    if (in_num)
        putchar('*');
        
    return 0;
}

  • HJ97 记负均正(数组)

华为机试 108 题(C 语言解答)_第106张图片

输入:
11 
1 2 3 4 5 6 7 8 9 0 -1

输出:
1 5.0

示例代码:HJ97.c


#include 

int main(void)
{
    int n;
    int num;
    int count_p = 0, count_n = 0;
    int total = 0;
    int i;
    float average;
    
    scanf("%d", &n);
    for (i = 0; i < n; i++)
    {
        scanf("%d", &num);
        if (num < 0)
            count_n++;
        else if (num > 0)
        {
            total += num;
            count_p++;
        }        
    }
    if (total > 0)
        average = (float) total / count_p;
    else
        average = 0.0;
    printf("%d %.1f\n", count_n, average);
    
    return 0;
}

  • HJ98 自动售货系统(字符串)

华为机试 108 题(C 语言解答)_第107张图片
华为机试 108 题(C 语言解答)_第108张图片
华为机试 108 题(C 语言解答)_第109张图片
华为机试 108 题(C 语言解答)_第110张图片
华为机试 108 题(C 语言解答)_第111张图片
华为机试 108 题(C 语言解答)_第112张图片
华为机试 108 题(C 语言解答)_第113张图片

输入:
r 22-18-21-21-7-20 3-23-10-6;c;q0;p 1;b A6;c;b A5;b A1;c;q1;p 5;


输出:
S001:Initialization is successful
E009:Work failure
E010:Parameter error
S002:Pay success,balance=1
E008:Lack of balance
1 yuan coin number=1
2 yuan coin number=0
5 yuan coin number=0
10 yuan coin number=0
E008:Lack of balance
E008:Lack of balance
E009:Work failure
E010:Parameter error
S002:Pay success,balance=5

示例代码:HJ98.c


#include 
#include 
#include 
#include 
#define PRONUM 6

char* s_gets(char *st, int n);

int main(void)
{
    int pro_price[PRONUM] = {2, 3, 4, 5, 8, 6};
    int pro_num[PRONUM] = {0};
    int money_box[4] = {0};         // 1, 2, 5, 10
    char str[1000];
    int tag_space = 0;
    int num, blance = 0;            // blance余额
    bool sold_out;
    int i, j;
     
    while (s_gets(str, 1000) != NULL)
    {
        int len = strlen(str);
        for (i = 0; i < len; i++)
        {
            while (str[i] != ';' && str[i] != '\0')
            {
                if (str[i] == 'r')               // 初始化钱盒,商品数量
                {                                
                    i++;
                    tag_space = 0;               // 判断命令与参数之间是否有空格
                    while (str[i] == ' ') 
                    {
                        i++;
                        tag_space = 1;
                    }
                    if (tag_space == 0)
                    {
                        printf("E010:Parameter error\n");
                        while (str[i] != ';')
                            i++;
                        break;
                    }
                    for (j = 0; j < PRONUM; j++) // 商品数量初始化
                    {
                        num = 0;
                        while (str[i] != '-' && !isspace(str[i]))
                        {
                            num = num * 10 + (str[i] - '0');
                            i++;
                        }
                        i++;
                        pro_num[j] = num;
                    }
                    while (str[i] == ' ')
                        i++;
                    for (j = 0; j < 4; j++)      // 钱盒初始化
                    {      
                        num = 0;
                        while (str[i] != '-' && str[i] != ';')
                        {
                            num = num * 10 + (str[i] - '0');
                            i++;
                        }
                        money_box[j] = num;
                        if (str[i] == ';') 
                            break;
                        i++;
                    }
                    blance = 0;
                    printf("S001:Initialization is successful\n");
                }
                else if (str[i] == 'p')          // 投币
                {                                
                    i++;
                    tag_space = 0;
                    while (str[i] == ' ') 
                    {
                        i++;
                        tag_space = 1; 
                    }
                    if (tag_space == 0)
                    { 
                        printf("E010:Parameter error\n");
                        while (str[i] != ';')
                            i++;
                        break;
                    }
                    num = 0;
                    while (str[i] != ';')        // 投币面值
                    {                            
                        num = num * 10 + (str[i] - '0');
                        i++;
                    }
                    sold_out = true;
                    for (j = 0; j < PRONUM; j++)
                    {
                        if (pro_num[j])
                            sold_out = false;
                    }
                    if (num != 1 && num != 2 && num != 5 && num != 10) 
                        printf("E002:Denomination error\n");
                    else if (num > 2 && 1 * money_box[0] + 2 * money_box[1] < num) 
                        printf("E003:Change is not enough, pay fail\n");
                    else if (sold_out)
                        printf("E005:All the goods sold out\n");
                    else if (num == 1) 
                    {
                        money_box[0]++;
                        blance += num;
                        printf("S002:Pay success,balance=%d\n",blance);
                    }
                    else if (num == 2) 
                    {
                        money_box[1]++;
                        blance += num;
                        printf("S002:Pay success,balance=%d\n",blance);
                    }
                    else if (num == 5)
                    {
                        money_box[2]++;
                        blance += num;
                        printf("S002:Pay success,balance=%d\n",blance);
                    }
                    else if (num == 10)
                    {
                        money_box[3]++;
                        blance += num;
                        printf("S002:Pay success,balance=%d\n",blance);
                    }
                }
                else if (str[i] == 'b')         // 购买商品
                {                                
                    i++;
                    tag_space = 0;
                    while (str[i] == ' ')
                    {
                        i++;
                        tag_space = 1; 
                    }
                    if (tag_space == 0)
                    { 
                        printf("E010:Parameter error\n");
                        while (str[i] != ';')
                            i++;
                        break;
                    }
                    num = 0;
                    i++;                         // 跳过字母A
                    while (str[i] != ';')
                    {
                        num = num * 10 + (str[i] - '0');
                        i++;
                    }
                    if (num > 6)
                        printf("E006:Goods does not exist\n");
                    else if (pro_num[num - 1] == 0)
                        printf("E007:The goods sold out\n");
                    else if (blance >= pro_price[num - 1])
                    {
                        pro_num[num - 1]--;
                        blance -= pro_price[num -1];
                        printf("S003:Buy success,balance=%d\n",blance);
                    }
                    else 
                        printf("E008:Lack of balance\n");
                }
                else if (str[i] == 'c')          // 退币
                {                                
                    i++;
                    if (blance == 0) 
                        printf("E009:Work failure\n");
                    else
                    {
                        int ref1 = 0, ref2 = 0, ref5 = 0, ref10 = 0;
                        bool change;
                        while (blance > 0)
                        {
                            change = false;
                            if(money_box[0] == 0 && money_box[1] == 0 && money_box[2] == 0
                                && money_box[3] == 0)
                            {
                                break;
                            }
                            else if (blance >= 10 && money_box[3] > 0)
                            {
                                money_box[3]--;
                                blance -= 10;
                                ref10++;
                                change = true;
                            }
                            else if (blance >= 5 && money_box[2] > 0)
                            {
                                money_box[2]--;
                                blance -= 5;
                                ref5++;
                                change = true;
                            }
                            else if (blance >= 2 && money_box[1] > 0)
                            {
                                money_box[1]--;
                                blance -= 2;
                                ref2++;
                                change = true;
                            }
                            else if (blance >= 1 && money_box[0] > 0)
                            {
                                money_box[0]--;
                                blance -= 1;
                                ref1++;
                                change = true;
                            }
                            if (!change)         // 表明无钱可退 
                                break; 
                        }
                        printf("1 yuan coin number=%d\n",ref1);
                        printf("2 yuan coin number=%d\n",ref2);
                        printf("5 yuan coin number=%d\n",ref5);
                        printf("10 yuan coin number=%d\n",ref10);
                    }
                }
                else if (str[i] == 'q')         // 显示 0 商品,1 钱盒
                {                                
                    i++;
                    tag_space = 0;
                    while (str[i] == ' ')
                    {
                        i++;
                        tag_space = 1; 
                    }
                    if (tag_space == 0)
                    { 
                        printf("E010:Parameter error\n");
                        while (str[i] != ';')
                            i++;
                        break;
                    }
                    num = 0;
                    while (str[i] != ';')
                    {
                        num = num * 10 + (str[i] - '0');
                        i++;
                    }
                    if (num == 0)
                    {
                        for(j = 0; j < PRONUM; j++)
                            printf("A%d %d %d\n",j+1, pro_price[j], pro_num[j]);
                    }                 
                    else if (num == 1)
                    {
                        printf("1 yuan coin number=%d\n",money_box[0]);
                        printf("2 yuan coin number=%d\n",money_box[1]);
                        printf("5 yuan coin number=%d\n",money_box[2]);
                        printf("10 yuan coin number=%d\n",money_box[3]);
                    }
                    else
                        printf("E010:Parameter error\n");
                }
                i++;
            }
        }
    }
    
       return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val, * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find) 
            *find = '\0';
        else 
            while (getchar() != '\n') 
                continue;
    }
    
    return ret_val;
}

  • HJ99 自守数(基础数学)

华为机试 108 题(C 语言解答)_第114张图片

输入:6

输出:4

说明:有0,1,5,6这四个自守数     

示例代码:HJ99.c


#include 
#include 
#include 
#define LEN 20

bool judge(int num);
void print(int n);

int main(void)
{
    int n;
    
    scanf("%d", &n);
    print(n);
    
    return 0;
}

bool judge(int num)
{
    char str_o[LEN], str_s[LEN];
    int i, j;
    
    sprintf(str_o, "%d", num);
    sprintf(str_s, "%d", num * num);
    for (i = (int) strlen(str_o) - 1, j = (int) strlen(str_s)- 1; i > -1; i--, j--)
    {
        if (str_o[i] != str_s[j])
            return false;
    }
        
    return true;
}

void print(int n)
{
    int i;
    int count = 0;
    
    for (i = 0; i <= n; i++)
    {
        if (judge(i))
            count++;
    }
        
    printf("%d", count);
}

  • HJ100 等差数列(基础数学)

华为机试 108 题(C 语言解答)_第115张图片

输入:2

输出:7

说明:2+5=7

示例代码:HJ100.c


#include 
#define START 2
#define DIFF 3

int get_sum(int n);

int main(void)
{
    int n;
    
    scanf("%d", &n);
    printf("%d", get_sum(n));
    
    return 0;
}

int get_sum(int n)
{
    return (n * ( 2 * START + (n - 1) * DIFF)) / 2;
}

  • HJ101 输入整型数组和排序标识,对其元素按照升序或降序进行排序(排序)

华为机试 108 题(C 语言解答)_第116张图片

输入:
8
1 2 4 9 3 55 64 25
0

输出:
1 2 3 4 9 25 55 64

示例代码 1:HJ101.c


#include 

void sort(int ar[], int n, int choose);

int main(void)
{
    int n;
    int i;
    int choose;
    
    scanf("%d", &n);
    int ar[n];
    for (i = 0; i < n; i++)
        scanf("%d", ar + i);
    scanf("%d", &choose);
    sort(ar, n, choose);
    
    return 0;
}

void sort(int ar[], int n, int choose)
{
    int i, j;
    int temp;
    
    if (!choose)
    {
        for (i = 0; i < n - 1; i++)
        {
            for (j = i + 1; j < n; j++)
            {
                if (ar[i] > ar[j])
                {
                    temp = ar[i];
                    ar[i] = ar[j];
                    ar[j] = temp;
                }
            }
            printf("%d ", ar[i]);
        }
        printf("%d ", ar[i]);    
    }
    else
    {
        for (i = 0; i < n - 1; i++)
        {
            for (j = i + 1; j < n; j++)
            {
                if (ar[i] < ar[j])
                {
                    temp = ar[i];
                    ar[i] = ar[j];
                    ar[j] = temp;
                }
            }
            printf("%d ", ar[i]);
        }
        printf("%d ", ar[i]);
    }
}

示例代码 2:HJ101.c


#include 
#include 

int SBCompare(const void * p1, const void * p2);
int BSCompare(const void * p1, const void * p2);

int main(void)
{
    int n;
    int i;
    int choose;
    
    scanf("%d", &n);
    int ar[n];
    for (i = 0; i < n; i++)
        scanf("%d", ar + i);
    scanf("%d", &choose);
    if (choose == 0)
        qsort(ar, n, sizeof(int), SBCompare);
    if (choose == 1)
        qsort(ar, n, sizeof(int), BSCompare);
    for (i = 0; i < n; i++)
        printf("%d ", ar[i]);
    
    return 0;
}

int SBCompare(const void * p1, const void * p2)
{
    return *((int *) p1) - *((int *) p2);
}

int BSCompare(const void * p1, const void * p2)
{
    return *((int *) p2) - *((int *) p1);
}

  • HJ102 字符统计(字符串)

华为机试 108 题(C 语言解答)_第117张图片

输入:aaddccdc

输出:cda

说明:样例里,c和d出现3次,a出现2次,但c的ASCII码比d小,所以先输出c,再输出d,最后输出a.

示例代码:HJ102.c


#include 
#include 
#include 
#define SIZE 256
#define LEN 1001

int main(void)
{
    static int count[SIZE];
    char str[LEN];
    int max = 0;
    int i;
    
    scanf("%s", str);
    for (i = 0; i < (int) strlen(str); i++)
    {
        count[toascii(str[i])]++;
        if (count[toascii(str[i])] > max)
            max = count[toascii(str[i])];
    }
    while (max)
    {
        for (i = 0; i < SIZE; i++)
        {
            if (max == count[i])
                printf("%c",i);
        }    
        max--;
    }
    
    return 0;
} 

  • HJ103 Redraiment的走法(动态规划,最长子序列问题)

华为机试 108 题(C 语言解答)_第118张图片

输入:
6
2 5 1 5 4 5 

输出:
3

说明:
6个点的高度各为 2 5 1 5 4 5
如从第1格开始走,最多为3步, 2 4 5 ,下标分别是 1 5 6
从第2格开始走,最多只有1步,5
而从第3格开始走最多有3步,1 4 5, 下标分别是 3 5 6
从第5格开始走最多有2步,4 5, 下标分别是 5 6
所以这个结果是3。     

示例代码:HJ103.c


#include 
#include 
#define LEN 200

int get_max(int n, int ar[]);

int main(void)
{
    int n;
    int i;
    int * ar;
    
    while (scanf("%d", &n) == 1)
    {
        ar = (int *) malloc(sizeof(int) * n);
        for (i = 0; i < n; i++)
            scanf("%d", ar + i);
        printf("%d", get_max(n, ar));
        free(ar);    
    }
            
    return 0;
}

int get_max(int n, int ar[])
{
    int i, j;
    int step = 1;
    int dp[n];
    
    for (i = 0; i < n; i++)        // 初始化,如果本身就是最大值则不再更改该值 
        dp[i] = 1;
    for (i = 1; i < n; i++)        // 终点为 i 
    {
        for (j = 0; j < i; j++)
        {
            if (ar[i] > ar[j])
                dp[i] = (dp[i] > dp[j] + 1) ? dp[i] : dp[j] + 1;
        }
        step = (step > dp[i]) ? step : dp[i];
    }
    
    return step;
}

  • HJ105 记负均正II(数组)

华为机试 108 题(C 语言解答)_第119张图片

输入:
-13
-4
-7

输出:
3
0.0

示例代码:HJ105.c


#include 

int main(void)
{
    int num;
    int count_n = 0;
    int count_o = 0;
    int sum_o = 0;
    float average = 0.0;
    
    while (scanf("%d", &num) == 1)
    {
        if (num < 0)
            count_n++;
        else
        {
            count_o++;
            sum_o += num;    
        }    
    }
    if (sum_o > 0)
        average = (float) sum_o / count_o;
    printf("%d\n%.1f\n", count_n, average);
    
    return 0;
}

  • HJ106 字符逆序(字符串)

华为机试 108 题(C 语言解答)_第120张图片

输入:I am a student

输出:tneduts a ma I

示例代码:HJ106.c


#include 
#include 
#define LEN 10001

char * s_gets(char * st, int n);

int main(void)
{
    char str[LEN];
    int i;
    
    if (s_gets(str, LEN) != NULL && *str != '\0')
    {
        for (i = (int) strlen(str) - 1; i > -1; i--)
            putchar(str[i]);
    }
        
    return 0;
}

char * s_gets(char * st, int n)
{
    char * ret_val;
    char * find;
    
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        find = strchr(st, '\n');
        if (find)
            *find = '\0';
        else
            while (getchar() != '\n')
                continue;
    }
    
    return ret_val;
}

  • HJ107 求解立方根(二分查找)

华为机试 108 题(C 语言解答)_第121张图片

输入:19.9

输出:2.7

示例代码:HJ107.c


#include

int main() 
{
    double val;
    double l = -20.0;
    double r = 20.0;
    double mid;
    
    scanf("%lf", &val);
    while (val - l * l * l > 0.001)         // 从左侧逼近,不用考虑正负号,不错的策略 
    {
        mid = (l + r) / 2;
        if (mid * mid * mid < val) 
            l = mid;
        else
            r = mid; 
    }
    printf("%.1lf", l);
    
    return 0;
}

  • HJ108 求最小公倍数(基础数学)

华为机试 108 题(C 语言解答)_第122张图片

输入:5 7

输出:35

示例代码 1:HJ108.c


#include 

int get_com(int x, int y);

int main(void)
{
    int m, n;
    
    while (scanf("%d%d", &m, &n) == 2)
        printf("%d\n", get_com(m, n));
    
    return 0;
}

int get_com(int x, int y)
{
    int i;
    int com;
    
    for (i = 1; i <= y; i++)
    {
        if ((x * i) % y == 0)
        {
            com = x * i;
            break;
        }
    }
    
    return com;
}

示例代码 2:HJ108.c


#include 

int gcd(int m , int n);

int main(void)
{
    int m, n;
    
    while (scanf("%d%d", &m, &n) == 2)
        printf("%d", (m * n) / gcd(m, n));
    
    return 0;
}

int gcd(int m , int n)
{
    int temp;
    
    while (n)
    {
        temp = m % n;
        m = n;
        n = temp;
    }
    
    return m;
}

你可能感兴趣的:(#,C,Huawei,Code,算法,c语言)