天天看點

【網易互娛模拟筆試】解題記錄

08-04那天參加了一下網易互娛的模拟筆試,那天狀态不太好,再加上調試第一題花了很長時間,心态有點炸了,是以最後完成得并不理想。

總結:筆試心态還不夠穩,手速還不夠快,算法還不夠熟。

一共 3 道題,題目都很簡單,但是自己并沒有做完,汗顔羞愧。記錄一下。

第一題 個稅繳納

新稅收政策中,起征點是5000,超過5000的部分,需要進行分級納稅,請根據新納稅表計算個人所得稅,題目如圖:

【網易互娛模拟筆試】解題記錄

要求:

多行輸入,每行輸入月收入,假設無需繳納其他費用,請輸出計算出所需繳納的個人所得稅,稅費四舍五入。

實作:

// 計算個人所得稅,income: 個人收入, taxs: 匯率表
int calTax(int income, map<int, double> &taxs){
    int len = taxs.size();
    if(income <= 5000){
        return 0;
    }
    income  = income - 5000;
    int i   = 0;    // 記錄目前為第幾個區間
    int res = 0;
    map<int, double>::iterator iter_cur  = taxs.begin();      // 目前區間疊代器
    map<int, double>::iterator iter_next = ++taxs.begin();    // 下一區間疊代器,用于取得下一區間的起始值
    for(; iter_cur != taxs.end(); iter_cur++, iter_next++){
        if(income - iter_cur->first <= 0){
            break;
        }else{
            int range_tax;  // 目前區間所需繳納的稅額
            if(income >= iter_next->first && i < len - 1){  // 收入大于目前納稅區間的最大值,即大于下一區間的起始值時。并且目前區間不是最後一個區間
                range_tax = round((iter_next->first - iter_cur->first) * iter_cur->second);  // 直接區間值 * 區間稅率
            }else{
                range_tax = round((income - iter_cur->first) * iter_cur->second);            // 收入與區間起始值的差 * 區間稅率
            }
            res += range_tax;
            i++;
        }
    }
    return res;
}


int main(){
    int T;
    map<int, double> taxs = {   // 稅率表
        {0,     0.03},
        {3000,  0.1},
        {12000, 0.2},
        {25000, 0.25},
        {35000, 0.3},
        {55000, 0.35},
        {80000, 0.45}
    };

    cin >> T;
    while(T--){
        int N;
        int tax;
        cin >> N;
        cout << calTax(N, taxs) << endl;
    }
	return 0;
}
           

AC 100%

源碼位址

第二題 字元串縮寫

将4個及4個以上連續字典序的字母轉為"首個字母-結束字母"的形式。

如 “ABCABCDEFGABCD” → “ABCA-GA-D”。字母都為大寫字母,沒有其他字元。

【網易互娛模拟筆試】解題記錄

要求:

多行輸入,每行一個長度不超過5000的字元串。

輸出 縮寫後的字元串。

官方給出的解題思路:

【網易互娛模拟筆試】解題記錄

算法複雜度是 O(N)

個人思路實作:

// 壓縮字元串函數,傳回縮寫後的字元串
string compressString(string str){
    int len = str.size();
    if(len < 4){
        return str;
    }
    string res = "";        // 傳回結果
    string sub_str = "";    // 用于暫存子串
    int i = 0;
    for(; i < len - 1; i++){
        if(str[i] + 1 == str[i + 1]){
            sub_str += str[i];
        }else{
            if(sub_str.size() >= 3){
                res = res + sub_str[0] +  "-" + str[i];
            }else{
                res = res + sub_str + str[i];
            }
            sub_str = "";   // 初始化
        }
    }

    if(sub_str.size() >= 3 && str[i - 1] + 1 == str[i]){  // 因為 str[len - 1] 尚未周遊,是以還需再判斷一次
        res = res + sub_str[0] + "-" + str[i];
    }else{
        res = res + sub_str + str[i];
    }
    return res;
}


int main(){
    int T;
    cin >> T;
    while(T--){
        string s;
        cin >> s;
        cout << compressString(s) << endl;
    }
	return 0;
}
           

源碼位址

第三題

由于打字員失誤,整數 N 的 X 進制和 Y 進制連在一起輸出了,請根據X、Y兩個進制連起來的字元串,識别出這個整數 N 的十進制值。資料保證隻有一個解。

【網易互娛模拟筆試】解題記錄

要求:

多行輸入,每行輸入為 X Y Z 的形式,2 <= X, Y <= 16,Z 為 N 的 X 進制及 Y 進制連起來的字元串,請根據 X Y Z 識别出 N,并輸出 N 的十進制。10 ~ 15 用大寫 A ~ F 表示。0 < N < 2^31 - 1

輸入:13 7 1016

輸出:13

官方思路:

【網易互娛模拟筆試】解題記錄
【網易互娛模拟筆試】解題記錄

個人思路實作:

// 進制轉換函數, 将 k 機制字元串轉換為十進制數
long long kToDec(int k, string str){
   int len = str.size();
   long long res = 0;
   for(int i = 0; i < len; i++){
       if(str[i] >= 'A' && str[i] <= 'F'){
           res = res * k + (str[i] - 'A') + 10;
       }else{
           res = res * k + (str[i] - '0');
       }
   }
   return res;
}

// 識别數字函數,傳回識别結果
long long identifyNum(int x, int y, string str){
   int len  = str.size();
   int left = 0;
   int right = len - 1;
   while(left < right ){           // 使用二分法尋找兩種進制的“中位數”
       int median = (left + right) / 2;
       long long num1   = kToDec(x, str.substr(0, median + 1)); // 左子串轉換成十進制
       long long num2   = kToDec(y, str.substr(median + 1));    // 右子串轉換成十進制
       if(num1 < num2){
           left = median + 1;
       }else if(num1 > num2){
           right = median;
       }else{
           return num1;
       }
   }
   return -1;
}

int main(){
   int T;          // 樣例數
   cin >> T;
   while(T--){
       int X, Y;   // X 進制,Y 進制,
       string Z;   // 為數字字元串
       cin >> X >> Y >> Z;   // 最大輸入示例:2 16 11111111111111111111111111111111FFFFFFFF
       cout << identifyNum(X, Y, Z) << endl;
   }
   return 0;
}
           

源碼連結

第二、第三題我參考了一個哥們三題全AC的代碼,他是用JAVA寫的,感興趣的可以去看看,參考連結:

https://www.nowcoder.com/discuss/216766

繼續閱讀