A DeepSeek's Infinite Coffee Break

输出题,输出Server is busy, please try again later.即可

代码:

void solve() {
    cout << "Server is busy, please try again later.";
} 

B 工资转换

表达式题,对输入的值进行单位换算后保留三位小数输出即可

单位换算:1年=12月 1万元=10000元

代码:

void solve() {    
	int n;
	cin >> n;
	n *= 12;
    cout << fixed << setprecision(3) << n / 1e4;
}

C 谁是黑岩目高

对于每组输入的字符串,我们要将所有英文大写字符转换成小写,然后使用string的find()函数查找是否含有指定字符串即可。

注意使用getline()前将第一行的回车用 getchar(); / cin.get(); 读掉

代码:

void solve() {    
    string s;
    getline(cin,s);
    for(int i = 0;i < s.size();i++){
        s[i] = tolower(s[i]);
    }
    if(s.find("shinto mekkaku") != string::npos){
        cout << "Medaka Kuroiwa\n";
    }else{
        cout << "Bonnjinn\n";
	}
}

D 答案之页码之和

首先我们先看样例,5是可能的页码之和。然后通过计算得出5 = 2 + 3,也就是这本书的第1页是在书平铺开后的右侧。

那么这本书的第二、三个合法的页码之和分别为4 + 5 = 9,6 + 7 = 13。我们发现9 – 5 = 4,13 – 9 = 4。

也就是从5开始每增加4即为一个合法的页码之和。

代码:

void solve() {
    int x;
    cin >> x;
    if((x - 5) % 4 == 0){
        cout << "YES\n";
    }else{
        cout << "NO\n";
    }
}

E 睡眠质量

总体来说应该只有清醒不计入睡眠时长各位可能会想不到,其他都是按题意模拟。(这里为第四个测试点错误向各位谢个罪)

UPD: 参考代码写法可能存在精度问题,各位可以给分子先乘个100再计算。

代码:

void solve(){
    int n;
    cin >> n;
    long long arr[3] = {0};
    double sum = 0;
    for(int i = 1;i <= n;i++){
        int a,b;
        cin >> a >> b;
        if(a == 3) continue;
        arr[a] += b;
        sum += b;
    }
    if(arr[2] / sum >= 0.2 && arr[2] / sum <= 0.6){
        if(arr[1] / sum < 0.55 && (arr[0] / sum >= 0.1 && arr[0] / sum <= 0.3)){
            cout << "Great! ";
        }else if(arr[1] / sum >= 0.55 && (arr[0] / sum < 0.1 || arr[0] / sum > 0.3)){
            cout << "Little Bad ";
        }else{
            cout << "Normal ";
        }
    }else{
        cout << "Bad! ";
    }
    cout << sum << "\n";
}

F xiaoxiao的连续自然数和吗?(Hard Version)

通过观察得知,答案就是s开始连续n个数。(因为是我灵光一现想到的题目,没有进行数学上的证明,如果你会,可以发在评论区里)

代码:

void solve(){
    long long n,s;
    cin >> n >> s;
    for(int i = 0;i < n;i++){
        if(i) cout << " ";
        cout << s + i;
    }
}

G Abandon

STL容器题,我们首先要知道set容器存储数据时就是按字典序的,然后把每个单词首字母转大写丢进map里就行了。(应该没人不会判断是不是短语吧)

不过这题对于细节其实卡的比较死,既要关流同步,又要引用,还不能endl。

代码:

void solve(){
    string s;
    map<char,set<string>> dc;
    map<char,set<string>> dy;
    while(getline(cin,s)){
        if(s.find(" ") != string :: npos){
            dy[toupper(s[0])].insert(s);
        }else{
            dc[toupper(s[0])].insert(s);
        }
    }
    for(char c = 'A';c <= 'Z';c++){
        long long total = dc[c].size() + dy[c].size();
        if(total != 0){
            cout << c << " " << total << "\n";
        }else{
            continue;
        }
        if(dc[c].size() != 0){
            for(auto& s : dc[c]){
                cout << s << "\n";
            }
        }
        if(dy[c].size() != 0){
            for(auto& s : dy[c]){
                cout << s << "\n";
            }
        }
    }
}

H 简单题:一元一次方程

参考数学中的解法,将所有含 x 的项系数移到左边,常数项移到右边。

遍历字符串,以等号“=”作为临界点,逐项处理符号和数字。

最终解为 x = 右边常数和 / 左边系数和,注意消除 -0 并保留两位小数。时间复杂度为O(n)。

代码:

void solve(){
    int left = 0, right = 0;
    // 思路:把含未知数x的系数全放在等号左边,其余放在等号右边
    string s;
    cin >> s;
    int i, n = 0, k = 1; // n 表示获取的数字,k 表示获取的运算符
    // 先计算等号左边
    for (i = 0; i < s.size(); i++){
        if (isdigit(s[i])) {
            n = n * 10 + (s[i] - '0');
        } else {
            if (s[i] == 'x') {
                if (n == 0) n = k * 1;
                left += k * n;
                k = 1;
            } else {
                if (n != 0) {
                    right -= k * n;
                    k = 1;
                }
                if (s[i] == '-') k = -1;
            }
            n = 0;
        }
        if (s[i] == '=') break;
    }
    // 再计算等号右边
    for (; i < s.size(); i++){
        if (isdigit(s[i])) {
            n = n * 10 + (s[i] - '0');
        } else {
            if (s[i] == 'x') {
                if (n == 0) n = k * 1;
                left -= k * n;
                k = 1;
            } else {
                if (n != 0) {
                    right += k * n;
                    k = 1;
                }
                if (s[i] == '-') k = -1;
            }
            n = 0;
        }
    }
    double ans = 1.0 * right / left;
    if (ans == -0) ans = 0;
    cout << "x = " << fixed << setprecision(2) << ans << "\n";
}

I 小军的操作系统没有挂

由该题题意可知,我们定义一个结构体来存储这三个整数(线程到达时间、运行时间以及它的优先权),在定义线程的结束时间还有标记它是否已经被cpu运行和它的id。

再根据优先级进行排序,如果优先级相同,则按照线程的顺序(即id)进行排序。

此时我们可以按照这个思路来进行找线程的执行顺序:

我们先把第一个进程进入cpu的时间先找出来,然后开始在未被cpu运行的线程里面,把开始时间小于此刻时间的线程拿来给cpu执行,再把该线程存入线程执行完的容器里面,然后把该进程的结束时间更新即(time += x.runtime;x.end = time;),如果没有找到小于此刻时间的线程,则把此刻时间++。

最后把存储运行完的线程的容器按顺序输出,把每个线程的运行时间加起来除以线程数,即可得到平均运行时间。 代码:

using ll = long long;
struct pai {
    ll begin, end, runtime;
    int id, pry, f;
};

pai p[100001];
int n;

bool cmp1(pai a, pai b) {
    if (a.pry == b.pry) return a.id < b.id;
    return a.pry > b.pry;
}

pai maxx(ll time) {
    for (int i = 0; i < n; i++) {
        if (p[i].f == 0 && p[i].begin <= time) {
            p[i].f = 1;
            return p[i];
        }
    }
    return {0, 0, 0, 0, 0, 0};  // 返回一个默认值来代替 "null"
}

void solve() {
    cin >> n;
    ll minn = 1e18;
    for (int i = 0; i < n; i++) {
        cin >> p[i].begin >> p[i].runtime >> p[i].pry;
        p[i].id = i + 1;
        p[i].f = 0;  // 初始化状态
        minn = min(minn, p[i].begin);
    }

    sort(p, p + n, cmp1);

    int m = n;
    ll time = minn;
    vector<pai> v;

    while (m > 0) {
        pai x = maxx(time);
        if (x.id == 0) {  // 如果没有找到合适的任务,增加时间
            time++;
        } 
		else {
            m--;
            time += x.runtime;
            x.end = time;
            v.push_back(x);  // 使用 push_back 添加任务
        }
    }

    int k = 0;
    double sum = 0;
    for (auto i : v) {
        if (k == 0) cout << "p" << i.id;
        else cout << ",p" << i.id;
        k++;
        sum += (i.end - i.begin);
    }
    cout << endl;
    printf("%.2f", sum / n);  // 输出平均运行时间
}

J Hot Path Delivery!

本质就是用BFS找迷宫最短路,辣椒粉只有一层的点就是可以走的点。(貌似按层BFS会更快。)

代码:

int dir[8][2] = {-1,0,1,0,0,1,0,-1,1,1,-1,1,-1,-1,1,-1};

struct Position{
    int x,y;
};

void add(vector<vector<int>>& arr,int x,int y,int n,int m){
    for(int i = 0;i < 8;i++){
        int nxtx = x + dir[i][0];
        int nxty = y + dir[i][1];
        if(nxtx >= 1 && nxtx <= n && nxty >= 1 && nxty <= m){
            arr[nxtx][nxty]++;
        }
    }
}

int bfs(vector<vector<int>>& arr,Position p,int n,int m){
    int cnt = 0;
    queue<Position> q;
    q.push({1,1});
    arr[1][1] = 0;
    while(!q.empty()){
        int size = q.size();
        cnt++;
        for(int i = 1;i <= size;i++){
            Position now = q.front();
            q.pop();
            for(int j = 0;j < 4;j++){
                Position nxt = {now.x + dir[j][0],now.y + dir[j][1]};
                if(nxt.x >= 1 && nxt.x <= n && nxt.y >= 1 && nxt.y <= m && arr[nxt.x][nxt.y] == 1){
                    if(nxt.x == p.x && nxt.y == p.y){
                        return cnt;
                    }
                    q.push(nxt);
                    arr[nxt.x][nxt.y] = 0;
                }
            }
        }
    }
    return -1;
}

void solve(){
    int n,m,ex,ey;
    cin >> n >> m >> ex >> ey;
    vector<vector<int>> arr;
    arr.push_back(vector<int>());
    for(int i = 1;i <= n;i++){
        vector<int> arr2;
        arr2.push_back(0);
        for(int j = 1;j <= m;j++){
            arr2.push_back(0);
        }
        arr.push_back(arr2);
    }
    int k;
    cin >> k;
    for(int i = 1;i <= k;i++){
        int x,y;
        cin >> x >> y;
        add(arr,x,y,n,m);
        arr[x][y] = 2;
    }
    arr[1][1] = 1;
    arr[ex][ey] = 1;
    int ans = bfs(arr,{ex,ey},n,m);
    if(ans == -1){
        cout << "cai jiu duo lian QAQ";
    }else{
        cout << ans;
    }
}

K 双模量子迷踪

题目要求在树塔中从顶到底找一条路径,使得综合得分(0.6×能耗 + 0.4×耗时)总和最小。

当得分相同时,优先选总能耗更小的路径。解法采用动态规划自底向上处理,每个节点选择下方两个子节点中得分较小的,得分相同选能耗低的,能耗相同选左边节点。

最后从顶回溯路径,记录总能耗、耗时及路径坐标。时间复杂度O(n²)。

代码:

struct node{
    int e, t; // 能耗和耗时
    double score; // 综合得分
};

void DP(int n){
    vector <vector<node>> dp (n, vector<node>(n));
    vector <vector<int>> path(n, vector<int>(n, 0));
    //输入树塔的数据
    int x, y;
    char c;
    for (int i = 0; i < n; i++)
        for (int j = 0; j <= i; j++){
            cin >> x >> c >> y;
            dp[i][j].score = 0.6 * x + 0.4 * y; // dp存储综合得分
            dp[i][j].e = x;
            dp[i][j].t = y;
        }
    //从倒数第二层往上处理数据
    for (int i = n-2; i >= 0; i--)
        for (int j = 0; j <= i; j++){
            if (dp[i+1][j].score < dp[i+1][j+1].score){
                dp[i][j].score += dp[i+1][j].score;
                path[i][j] = 0; // 0表示选择左下方
            } else if (dp[i+1][j].score > dp[i+1][j+1].score){
                dp[i][j].score += dp[i+1][j+1].score;
                path[i][j] = 1; // 1表示选择右下方
            } else {
                if (dp[i+1][j].e <= dp[i+1][j+1].e) {
                    dp[i][j].score += dp[i+1][j].score;
                    path[i][j] = 0;
                } else {
                    dp[i][j].score += dp[i+1][j+1].score;
                    path[i][j] = 1;
                }
            }
        }
    double score = dp[0][0].score;
    int e = 0, t = 0;
    vector <int> p(n);
    int cur = 0;
    for (int i = 0; i < n; i++){
        p[i] = cur;
        e += dp[i][cur].e;
        t += dp[i][cur].t;
        if (i < n-1) cur += path[i][cur];
    }
    
    cout << fixed << setprecision(2) << score << "\n";
    cout << e << " " << t << "\n";
    for (int i = 0; i < n; i++){
        if (i != 0) cout << " ";
        cout << "(" << i << "," << p[i] << ")";
    }
}

void solve(){
    int n;
    cin >> n;
    DP(n);
}

L 山脉守护者

本题直接按题意模拟超时,需维护一个数组,支持动态修改元素和查询区间内的“峰值”数量。

使用线段树进行优化。每次修改时,检查被修改位置及其相邻的三个位置是否是峰值,并更新树状数组。

查询时通过前缀和之差计算区间结果。时间复杂度为每次操作 O(log n)。

代码:

class FenwickTree {
private:
    vector<int> tree;
    int n;
public:
    FenwickTree(int size) : n(size), tree(size + 2, 0) {}

    void update(int idx, int delta) {
        while (idx <= n) {
            tree[idx] += delta;
            idx += idx & -idx;
        }
    }

    int query(int idx) {
        int res = 0;
        while (idx > 0) {
            res += tree[idx];
            idx -= idx & -idx;
        }
        return res;
    }
};

void solve(){
    int n, m;
    cin >> n >> m;
    vector<int> a(n + 2); // 使用a[1..n],a[0]和a[n+1]作为边界
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
    }

    vector<int> peak(n + 2, 0); // peak[i]表示位置i是否是峰值
    FenwickTree bit(n);

    // 初始化峰值数组
    for (int i = 2; i <= n - 1; ++i) {
        if (a[i] > a[i - 1] && a[i] > a[i + 1]) {
            peak[i] = 1;
            bit.update(i, 1);
        }
    }

    while (m--) {
        int op;
        cin >> op;
        if (op == 1) {
            int k, h;
            cin >> k >> h;
            a[k] = h;
            // 检查k-1, k, k+1三个位置
            for (int i : {k - 1, k, k + 1}) {
                if (i < 2 || i > n - 1) continue;
                int new_peak = (a[i] > a[i - 1] && a[i] > a[i + 1]) ? 1 : 0;
                if (peak[i] != new_peak) {
                    int delta = new_peak - peak[i];
                    peak[i] = new_peak;
                    bit.update(i, delta);
                }
            }
        } else {
            int l, r;
            cin >> l >> r;
            if (r - l < 2) {
                cout << "0\n";
            } else {
                int sum_r_1 = bit.query(r - 1);
                int sum_l = bit.query(l);
                cout << sum_r_1 - sum_l << "\n";
            }
        }
    }
}