【荣耀校园招聘 软件开发工程师-通用软件】2024-10-08(AK)

三道编程题

T1 计算ID数量(100’)

小华刚刚参加了一个编译器课程,他想设计实现自己的编译器。首先,他设计了一种语言,他的语言最大支持N个字不同的字符,并且他规定了由这些字符组成的ID,任何ID的长度需要大于等于1且小于等于L个字符,他希望设计一个程序知道他的语言总共能组成多少个ID。例如,当N = 2(假设字符可以是0或1),并且L = 3时,他具有如下的ID:
{0,1,00,01,10,11,000,001,010,011,100,101,110,111},因此当N = 2, L = 3时总共有14种ID。
你需要编写一个程序,可以帮助小华找到可能的ID的总数。由于答案可能非常大,最后的结果需要对1000000007取余。

输入描述

输入包含多个用例。每个用例将为包含两个整数N和L的一行。N是可以作为id的部分的字符数,L是该语言支持的最大长度(1<=N<=65535,1 0<=L<=10^5)
当N=0并且L等于0时表示输入结束

输出描述

对每个用例输出一行ID的总数

示例 1
输入

2 3
100 15
0 0

输出

14
979451521

C++实现代码

#include <iostream>
using namespace std;

const int MOD = 1000000007;

long long recurPow(int x, int n) {
    if(n == 1) {
        return x % MOD;
    }
    long long res = recurPow(x, n / 2);
    if(n % 2 == 1) {
        return x * res * res % MOD;
    } else {
        return res * res % MOD;
    }
}

long long ppow(int x, int n) {
    long long ans = 1;
    if(n == 0) {
        return ans;
    } 
    long long t = n;
    return recurPow(x, t) % MOD;
}

long long powerMode(long long base, long long exp) {
    long long res = 1;
    while(exp > 0) {
        if(exp % 2 == 1) {
            res = (res * base) % MOD;
        }
        base = (base * base) % MOD;
        exp /= 2;
    }
    return res;
}

int main() {
    int N, L;
    while(cin>> N>> L) {
        if(N == 0 && L == 0) {
            break;
        }
        long long res = 0;
        for(int i = 1; i <= L; i++) {
            // res = (res + ppow(N, i)) % MOD;
            res = (res + powerMode(N, i)) % MOD;
        }
        cout << res<< endl;
    }
}
// 64 位输出请用 printf("%lld")

T2 计算输入复数的绝对值(200’)

输入描述

两个输入,第一个是复数的实部,第二个是复数的虚部

输出描述

绝对值(打印出整数即可)

示例 1
输入

7308
1839

输出

7536

C++实现代码

#include <iostream>
#include <cmath>
using namespace std;

int main() {
    long long real, fake;
    cin>> real>> fake;
    double res = sqrt(real * real + fake * fake) + 0.5;
    cout << static_cast<int>(res)<< endl;
}
// 64 位输出请用 printf("%lld")

T3 简易行编译器实现(300’)

实现一个简易行编辑器,根据编辑指令输出最后结果。编辑指令包括以下几种:
i 指令,在指定行前插入一行
a 指令,在指定行后增加一行
r 指令,整体替换指定行
d 指令,删除指定行

| 指令,前面几条指令通过该指令可执行复合操作,前一条指令的输出作
为后一条指令的输入。

输入描述

程序以一个字符串作为输入,此字符串可以是一条指令,也可以是多条指令组合成的复合指令:
a、i、r 指令格式: 行号 指令名 行内容
d 指令格式: 行号 指令名
| 指令格式: 指令1|指令2|指令3|…
行号、指令名、行内容之间以空格分离,行号表示对该指定行做编辑操作
初始状态下,行号为1,只能执行 i 指令,否则指令错误
行号从1开始计数,并且小于等于当前总行数,否则指令错误
其它指令为错误指令
行内容不考虑换行
复合指令下,不考虑行内容中包括“|”的情况

输出描述

如果指令错误,打印"error”
如果正确执行,打印指令执行的最后结果

示例 1
输入

1 i first line

输出

first line

示例 2
输入

1 i first linel1 a second line

输出

first line
second line

示例3
输入

1 i first linel1 a second linel2 r replace a line

输出

first line
replace a line

示例 4
输入

1 i first linel1 a second line|2 d

输出

first line

示例 5
输入

1 a first line|1 a second line

输出

error

C++ 实现代码

#include <iostream>
#include <functional>
#include <bits/stdc++.h>
#include <sstream>
using namespace std;

string join(const vector<string>& vec) {
    stringstream ss;
    for(size_t i = 0; i < vec.size(); i++) {
        if(i > 0) {
            ss << ' ';
        }
        ss<< vec[i];
    }
    return ss.str();
}

int main() {
    vector<string> txt;
    string line;
    getline(cin, line);
    istringstream iss(line);
    // 只有单个命令,没有复合语句
    if(line.find('|') == string::npos) {
        int num;
        string tmp;
        iss >> tmp;
        num = stoi(tmp);
        if(num != 1) {
            cout << "error" << endl;
            return 0;
        } 
        iss >> tmp;
        if(tmp != "i") {
            cout << "error" << endl;
            return 0;
        }
        string fullInput;
        getline(iss, fullInput);
        cout << fullInput.substr(1)<< endl;
        return 0;
        // 有复合语句
    } else {
        string part;
        while(getline(iss, part, '|')) {
            txt.push_back(part);
        }

        vector<string> ans;
        istringstream firstCommand(txt[0]);
        vector<string> x;

        while(firstCommand>> part) {
            x.push_back(part);
        }
        
        // 1 i first linel1 a second line
        ans.push_back(join(vector<string>(x.begin() + 2, x.end())));
        // ans里就是 first line

        for(size_t i = 1; i < txt.size(); i++) {
            istringstream curCommand(txt[i]);
            vector<string> t;
            while(curCommand >> part) {
                t.push_back(part);
            }

            int index = stoi(t[0]);
            if(index > ans.size()) {
                cout <<"error"<< endl;
                return 0;
            }

            if(t[1] == "i") {
                ans.insert(ans.begin() + index - 1, join(vector<string>(t.begin() + 2, t.end())));
            } else if(t[1] == "a") {
                ans.insert(ans.begin() + index, join(vector<string>(t.begin() + 2, t.end())));
            } else if(t[1] == "r") {
                ans[index - 1] = join(vector<string>(t.begin() + 2, t.end()));
            } else {
                if(index - 1 >= 0 && index - 1 < ans.size()) {
                    ans.erase(ans.begin() + (index - 1));
                } else {
                    cout << "error" << endl;
                    return 0;
                }
            }
        }
        for(const auto& item: ans) {
            cout << item<< endl;
        }
    }
    return 0;
}

之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值