当前位置:首页 > 技术 > 正文内容

Codeforces 984 赛题题解与实现

访客 技术 2026年7月19日 1

Codeforces 984 赛题题解与实现

https://codeforces.com/contest/2036

A

题目要求判断序列中相邻元素的差值是否只能是5或7。我们可以遍历整个序列,检查每一对相邻元素是否满足这个条件。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200005;
int sequence[MAXN];

bool validateSequence(int length) {
    for (int i = 1; i < length; i++) {
        int diff = abs(sequence[i] - sequence[i-1]);
        if (diff != 5 && diff != 7) {
            return false;
        }
    }
    return true;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int testCases;
    cin >> testCases;
    
    while (testCases--) {
        int n;
        cin >> n;
        
        for (int i = 0; i < n; i++) {
            cin >> sequence[i];
        }
        
        if (validateSequence(n)) {
            cout << "Yes\n";
        } else {
            cout << "No\n";
        }
    }
    
    return 0;
}

B

本题需要计算每种品牌的价值总和,并选取价值最高的前n个品牌。由于数据规模不大,我们可以使用数组存储各品牌价值,排序后直接选取前n个最大的值。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200005;
int brandValues[MAXN];

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int testCases;
    cin >> testCases;
    
    while (testCases--) {
        int n, k;
        cin >> n >> k;
        
        // Reset brand values
        fill(brandValues, brandValues + MAXN, 0);
        
        // Read and accumulate brand values
        for (int i = 0; i < k; i++) {
            int brand, value;
            cin >> brand >> value;
            brandValues[brand] += value;
        }
        
        // Sort in descending order
        sort(brandValues, brandValues + MAXN, greater<int>());
        
        // Sum top n brands
        long long total = 0;
        for (int i = 0; i < min(n, MAXN); i++) {
            total += brandValues[i];
        }
        
        cout << total << '\n';
    }
    
    return 0;
}

C

题目要求统计字符串中"1100"模式的出现次数,并处理多次修改操作。每次修改只会影响局部区域,我们可以通过检查修改前后的变化来高效更新计数。

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

bool checkPattern(const string &s, int position) {
    if (position < 0 || position + 4 > s.length()) {
        return false;
    }
    return s[position] == '1' && s[position+1] == '1' && 
           s[position+2] == '0' && s[position+3] == '0';
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int testCases;
    cin >> testCases;
    
    while (testCases--) {
        string text;
        int queries;
        cin >> text >> queries;
        
        // Add a dummy character at the beginning for 1-based indexing
        text = " " + text;
        int n = text.length();
        
        int patternCount = 0;
        // Count initial patterns
        for (int i = 1; i <= n - 4; i++) {
            if (checkPattern(text, i)) {
                patternCount++;
            }
        }
        
        while (queries--) {
            int index;
            char newChar;
            cin >> index >> newChar;
            
            // Check if the change actually affects the string
            if (text[index] == newChar) {
                continue;
            }
            
            // Check positions that might be affected by the change
            for (int i = max(1, index-3); i <= min(n-4, index); i++) {
                if (checkPattern(text, i)) {
                    patternCount--;
                }
            }
            
            // Apply the change
            text[index] = newChar;
            
            // Check positions that might be affected after the change
            for (int i = max(1, index-3); i <= min(n-4, index); i++) {
                if (checkPattern(text, i)) {
                    patternCount++;
                }
            }
            
            cout << (patternCount > 0 ? "Yes\n" : "No\n");
        }
    }
    
    return 0;
}

D

对于矩阵的每一层,按顺时针方向提取数据。由于只需要判断4位连续的模式,我们在提取的数据末尾添加前三个字符形成环形结构,然后统计"1543"模式的出现次数。

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

bool checkPattern(const string &s, int position) {
    if (position < 0 || position + 4 > s.length()) {
        return false;
    }
    return s[position] == '1' && s[position+1] == '5' && 
           s[position+2] == '4' && s[position+3] == '3';
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int testCases;
    cin >> testCases;
    
    while (testCases--) {
        int rows, cols;
        cin >> rows >> cols;
        
        vector<string> grid(rows);
        for (int i = 0; i < rows; i++) {
            cin >> grid[i];
        }
        
        int totalPatterns = 0;
        int layer = 0;
        
        while (rows > 2 * layer && cols > 2 * layer) {
            string spiral;
            int x = layer, y = layer;
            
            // Right
            while (y < cols - layer) {
                spiral += grid[x][y++];
            }
            y--;
            x++;
            
            // Down
            while (x < rows - layer) {
                spiral += grid[x++][y];
            }
            x--;
            y--;
            
            // Left
            while (y >= layer) {
                spiral += grid[x][y--];
            }
            y++;
            x--;
            
            // Up
            while (x > layer) {
                spiral += grid[x--][y];
            }
            
            // Make it circular by adding first 3 characters at the end
            spiral += spiral.substr(0, 3);
            
            // Count patterns
            for (int i = 0; i < spiral.length() - 3; i++) {
                if (checkPattern(spiral, i)) {
                    totalPatterns++;
                }
            }
            
            layer++;
        }
        
        cout << totalPatterns << '\n';
    }
    
    return 0;
}

E

我们需要预处理一个二维数组,利用按位或操作的单调性进行二分查找来确定范围。需要注意的是,应将列索引作为第一维以便于二分操作,同时要特别注意边界条件的处理。

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

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int rows, cols, queries;
    cin >> rows >> cols >> queries;
    
    // Preprocess the grid column-wise
    vector<vector<int>> columnOr(cols, vector<int>(rows));
    for (int j = 0; j < cols; j++) {
        for (int i = 0; i < rows; i++) {
            int value;
            cin >> value;
            if (i == 0) {
                columnOr[j][i] = value;
            } else {
                columnOr[j][i] = columnOr[j][i-1] | value;
            }
        }
    }
    
    while (queries--) {
        int left = 1, right = rows, valid = 0;
        int operations;
        cin >> operations;
        
        while (operations--) {
            int col;
            char op;
            int value;
            cin >> col >> op >> value;
            col--;
            
            if (op == '<') {
                // Find the first position where columnOr[col][i] >= value
                int pos = lower_bound(columnOr[col].begin(), columnOr[col].end(), value) - columnOr[col].begin();
                if (pos == 0) {
                    valid = 1;
                } else {
                    right = min(right, pos);
                }
            } else {
                // Find the first position where columnOr[col][i] > value
                int pos = upper_bound(columnOr[col].begin(), columnOr[col].end(), value) - columnOr[col].begin();
                if (pos == rows) {
                    valid = 1;
                } else {
                    left = max(left, pos);
                }
            }
        }
        
        if (valid || left > right) {
            cout << -1 << '\n';
        } else {
            cout << left << '\n';
        }
    }
    
    return 0;
}

F

利用连续自然数异或的特殊性质,我们可以推导出从0到x的异或结果规律。对于区间内满足特定模条件的数,我们可以将其分解为两部分计算:满足模条件的部分和剩余部分,最后组合得到结果。

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

// Function to compute XOR from 0 to x
long long xorRange(long long x) {
    if (x <= 0) return 0;
    
    switch (x % 4) {
        case 0: return x;
        case 1: return 1;
        case 2: return x + 1;
        case 3: return 0;
        default: return 0;
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int testCases;
    cin >> testCases;
    
    while (testCases--) {
        long long left, right, exponent, modulus;
        cin >> left >> right >> exponent >> modulus;
        
        // Compute XOR from left to right
        long long total = xorRange(right) ^ xorRange(left - 1);
        
        // Calculate the range of j values
        right = (right - modulus) >> exponent;
        left = ((left - modulus + (1LL << exponent) - 1) >> exponent);
        
        if (left < 0) left = 0;
        
        // If the count is odd, include the modulus
        if ((right - left + 1) & 1) {
            total ^= modulus;
        }
        
        // XOR the higher bits
        total ^= (xorRange(right) ^ xorRange(left - 1)) << exponent;
        
        cout << total << '\n';
    }
    
    return 0;
}

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

linux screen 用法详情 (nohup 的替代方案)

一、screen 是什么?能干嘛?screen 是一个终端复用器,可以:在一个 SSH 会话中开多个“虚拟终端”SSH 断线后,程序仍然在后台运行随时重新连接到原来的会话特别适合:nohup 的替代方案跑脚本 / 爬虫 / 训练模型运维、远程开发二、安装 screen# CentOS / Rocky / Almayum install -y screen# Debian / Ubuntuapt i...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。