1. 程式人生 > >小米 OJ 賽題——高弗雷勳爵(2018年09月13日 17:30 ~ 19:00)

小米 OJ 賽題——高弗雷勳爵(2018年09月13日 17:30 ~ 19:00)

題目描述

第七軍團的據點有數不清的敵人,高弗雷拿著一把附魔火槍,射出的子彈會在敵人間跳躍,一發子彈就能對所有敵人造成 2 點傷害,如果該子彈導致了任意敵人死亡(即血量小於等於 0),該子彈還會再次對所有敵人造成2點傷害,直到沒有新的敵人死亡為止。那麼,高弗雷需要打出幾顆子彈才能消滅所有敵人呢?

要求

輸入

  • 輸入是每個敵人的血量,用空格分開,回車結束。0<敵人的數量<=10000; 0<敵人的血量<=10^9

輸出

  • 輸出是一個數字,是高弗雷最少需要打出的子彈的個數
  • 輸出內容為只出現過唯一一次的數字

樣例

  • 輸入樣例:1 12 3 6 10
  • 輸出樣例:2
  • 輸入樣例:44 55 66 77 99 88
  • 輸出樣例:45
  • 輸入樣例:19 18 17 14 16 15 13 11 12 20
  • 輸出樣例:6
  • 輸入樣例:28 12 30 25 14 18 27 16 25 11 20
  • 輸出樣例:8

圖片描述

解題

初始程式碼:

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

#define BUFFERSIZE 1000000

int main()
{
    char line[1000001];

    // 迴圈讀入多行資料
    while (scanf("%s", &line) != EOF) {
        // 處理並輸出結果,務必輸出換行符
        // printf("%d\n", ans);
    }

    return 0;
}

第一步,獲取字串輸出,使用 fgets 函式替代 gets 函式獲取一整行輸入。fgets 函式與 gets 函式的不同在於 fegts 可以通過第二個引數來限制讀入字元數來解決溢位問題。

while (fgets(line, BUFFERSIZE, stdin))
{
    int i = 0;         // 迴圈計數
    int c = 0;         // 子字串個數計數
    char **arr = NULL; // 指向動態二維字元陣列的指標
    c = split(line, ' ', &arr);
}

第二步,設計字串處理函式,將字串拆分成二維字元陣列。


// 功能:將字串按照某個字元分割成多個子字串,返回該組子串的集合
// 引數 1 :源字串
// 引數 2 : 間隔字元
// 引數 3 : 儲存子字串的二維數字的地址

int split(char *str, char c, char ***arr)
{
    int count = 1;     // 拆分後字串的個數
    int token_len = 1; // 單個字串的長度
    int i = 0;
    char *p;
    char *t;
    // 判斷要拆分成多少個子串
    p = str;
    while (*p != '\0')
    {
        if (*p == c)
            count++;
        p++;
    }
    // 申請 count 個指標單元
    *arr = (char **)malloc(sizeof(char *) * count);
    if (*arr == NULL)
        exit(1);
    // 為每個指標單元申請 token_len 長度的空間
    p = str;
    while (*p != '\0')
    {
        if (*p == c)
        {
            (*arr)[i] = (char *)malloc(sizeof(char) * token_len);
            if ((*arr)[i] == NULL)
                exit(1);
            token_len = 0;
            i++;
        }
        p++;
        token_len++;
    }
    // 迴圈到最後一個字元時,跳出了迴圈,單獨為最後一個子串申請空間
    (*arr)[i] = (char *)malloc(sizeof(char) * token_len);
    if ((*arr)[i] == NULL)
        exit(1);
    // 為動態分配的二維陣列第二維賦值
    i = 0;
    p = str;
    t = ((*arr)[i]);
    while (*p != '\0')
    {
        if (*p != c && *p != '\0')
        {
            *t = *p;
            t++;
        }
        else
        {
            *t = '\0';
            i++;
            t = ((*arr)[i]);
        }
        p++;
    }
    // 遍歷到最後一個字元時,單獨加結束符
    *t = '\0';
    // 避免野指標
    p = t = NULL;
    return count;
}

未完待續,會繼續更新完整!