【网易互娱模拟笔试】解题记录

寵の児 提交于 2019-11-26 13:54:19

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的字符串。
输出 缩写后的字符串。

实现:

// 压缩字符串函数,返回缩写后的字符串
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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!