[ABC378C] Repeating 题解

文章摘要

智阅GPT

[ABC378C] Repeating 题解

解题思路

我们需要为每个 ​A_i 找到它在序列 ​A 中上一次出现的位置。你可能第一想法是使用桶来进行记录当前数在此之前的位置是什么。普通的桶在这一题显然是开不了的,因为数据量达到了 ​10^9。但其实使用map进行存储也同样可以通过本题。用map的思路比较好想,在这里重点讲一下通过排序实现本题的思路。

1. 数据结构选择

首先我们需要定义一个数据结构来存储每个元素的信息,包括该元素的值和它在原序列中的位置。我们可以使用一个结构体 node,其中 v 表示元素的值,p 表示元素的原始索引位置。

2. 排序

我们将所有的元素按照它们的值进行排序。排序后,相同的值会相邻排列。这样,我们只需要在相邻的元素中检查它们是否相同,如果相同,则说明它们是重复出现的,我们可以根据排序后的位置直接找到上一个出现的位置。

3. 填充结果

在遍历排序后的数组时,若当前元素的值和前一个元素相同,那么它的结果就是前一个元素的原始位置。否则,它的结果是 ​-1

4. 时间复杂度

排序的时间复杂度是 ​O(N \log N),然后遍历一次数组来填充结果是 ​O(N)。因此,总体时间复杂度是 ​O(N \log N),这个题是完全可以pass的。

AC代码

#include<bits/stdc++.h>
#define ll long long
#define mem(x,y) memset(x,y,sizeof(x))
#define CLOSE ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int inf=0x3f3f3f3f;
const int N=2e5+5;

int n, b[N];  // b数组用来存储结果
struct node {
    int p, v;  // p为元素在原数组中的位置,v为元素的值
} a[N];

bool cmp(node a, node b) {
    if(a.v == b.v) return a.p < b.p;  // 如果值相同,按位置排序
    return a.v < b.v;  // 如果值不同,按值排序
}

int main() {
    b[0] = -1;  // 初始化b数组的第一个值为-1,作为边界值
    cin >> n;  // 输入数组长度
    for(int i = 1; i <= n; i++) {
        cin >> a[i].v;  // 输入数组元素值
        a[i].p = i;  // 记录元素的原始位置
    }
  
    sort(a + 1, a + 1 + n, cmp);  // 按值排序

    // 填充b数组
    for(int i = 1; i <= n; i++) {
        if(a[i].v == a[i - 1].v) {
            b[a[i].p] = a[i - 1].p;  // 如果当前元素与前一个相同,则B[i]为前一个位置
        } else {
            b[a[i].p] = -1;  // 否则,B[i]为-1
        }
    }

    // 输出结果
    for(int i = 1; i <= n; i++) {
        cout << b[i] << " ";  // 输出每个B[i]值
    }

    return 0;
}

用键盘敲击出的不只是字符,更是一段段生活的剪影、一个个心底的梦想。希望我的文字能像一束光,在您阅读的瞬间,照亮某个角落,带来一丝温暖与共鸣。

ccxk

站长

不具版权性
不具时效性

文章内容不具时效性。若文章内容有错误之处,请您批评指正。


目录

欢迎来到ccxk的站点,为您导航全站动态

26 文章数
5 分类数
6 评论数
15标签数
最近评论
ccxk

ccxk


hi

ccxk

ccxk


Hi

Camelaaa_

Camelaaa_


热门文章

访问统计