河南萌新联赛2026第(一)场:河南工业大学J题题解
侧边栏壁纸
  • 累计撰写 9 篇文章
  • 累计收到 2 条评论

河南萌新联赛2026第(一)场:河南工业大学J题题解

llwqs
2026-07-28 / 0 评论 / 8 阅读 / 正在检测是否收录...

这道题的核心在于理解“交替共鸣序列”的定义,并找出删除哪一个元素后,剩下的序列能满足这个定义。
题目地址

解题思路

1.理解“交替共鸣序列”:

*   题目定义:序列中任意两个相邻元素的奇偶性都不同。
*   通俗理解:序列的奇偶性必须是交替出现的,例如 `奇, 偶, 奇, 偶` 或 `偶, 奇, 偶, 奇`。
*   特例:长度为 0 或 1 的序列天然满足条件。

2.分析删除操作:

*   我们需要尝试删除序列中的每一个元素,然后检查剩下的序列是否是“交替共鸣序列”。
*   直接模拟删除并检查的时间复杂度是 O(n²),对于 n ≤ 10⁶ 的数据规模会超时。我们需要一个 O(n) 的线性解法。

3.寻找高效方法:

*   一个序列如果不是“交替共鸣序列”,那一定是因为在某个位置 `i`,`a[i]` 和 `a[i+1]` 的奇偶性相同。我们称这个位置为“冲突点”。
*   当我们删除一个元素 `a[k]` 时,只会影响 `a[k-1]` 和 `a[k+1]` 之间的关系。序列中其他所有相邻元素的奇偶关系都保持不变。
*   因此,我们可以先遍历一遍原数组,找出所有“冲突点”的位置。
*   然后,对于每一个可能的删除位置 `k`,我们只需要检查:
    *   删除 `a[k]` 是否会消除原有的冲突?
    *   删除 `a[k]` 是否会引入新的冲突(即 `a[k-1]` 和 `a[k+1]` 的奇偶性是否相同)?
*   如果删除 `a[k]` 后,整个序列不再有任何冲突,那么 `k` 就是一个合法的删除位置。

4.算法步骤:

*   **预处理**:遍历数组,用一个数组 `conflicts` 记录所有冲突点的位置。`conflicts[i]` 为 `true` 表示 `a[i]` 和 `a[i+1]` 奇偶性相同。
*   **统计总冲突数**:计算 `conflicts` 数组中 `true` 的个数,记为 `total_conflicts`。
*   **遍历删除位置**:对于每个位置 `k` (从 0 到 n-1):
    *   计算删除 `a[k]` 会消除的冲突数 `removed_count`。这包括 `conflicts[k-1]` (如果 `k>0`) 和 `conflicts[k]` (如果 `k<n-1`)。
    *   计算删除 `a[k]` 会引入的新冲突数 `added_count`。这只发生在 `k>0` 且 `k<n-1` 时,检查 `a[k-1]` 和 `a[k+1]` 的奇偶性。
    *   如果 `total_conflicts - removed_count + added_count == 0`,则说明删除 `a[k]` 后序列是“交替共鸣序列”,答案加一。

完整代码

#include<bits/stdc++.h>
using namespace std;
bool panduan(long long a, long long b) {
    return (a & 1) == (b & 1);
}
void solve() {
    int n;
    cin >> n;
    vector<long long> a(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    if (n == 1) {
        cout << 1 << endl;
        return;
    }
    vector<bool> conflicts(n - 1, false);
    int total_conflicts = 0;
    for (int i = 0; i < n - 1; ++i) {
        if (panduan(a[i], a[i + 1])) {
            conflicts[i] = true;
            total_conflicts++;
        }
    }
    int ans = 0;
    for (int k = 0; k < n; ++k) {
        int removed_count = 0;
        int added_count = 0;
        if (k > 0 && conflicts[k - 1]) {
            removed_count++;
        }
        if (k < n - 1 && conflicts[k]) {
            removed_count++;
        }
        if (k > 0 && k < n - 1) {
            if (panduan(a[k - 1], a[k + 1])) {
                added_count++;
            }
        }
        if (total_conflicts - removed_count + added_count == 0) {
            ans++;
        }
    }
    cout << ans << endl;
}
int main() {
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}
0

评论 (0)

取消