【Acwing】【Campamento de entrenamiento de la Copa Blue Bridge】【Puntero doble】

Puntero doble: Complejidad del tiempo: O(n)

for (int i = 0, j = 0; i < n; i ++)
{
    
    
    while (j < i && check(i, j)) j ++;
    // 具体问题的逻辑
}
常见问题分类:
    (1) 对于一个序列,用两个指针维护一段区间
    (2) 对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作

Ejemplo 1:

Xiao Ming mantiene un foro de programadores. Ahora ha recopilado un registro de "me gusta", que tiene N líneas en total.

El formato de cada línea es:

ts id  

Indica que la publicación con id recibió un "me gusta" en el momento ts.

Ahora Xiao Ming quiere contar qué publicaciones alguna vez fueron "publicaciones calientes".

Si una publicación ha recibido no menos de K Me gusta en cualquier período de tiempo de duración D , Xiao Ming considera que esta publicación es una "publicación caliente".

Específicamente, si hay un cierto momento T que satisface que la publicación recibe no menos de K Me gusta dentro del período de [T, T + D) (tenga en cuenta que es el intervalo izquierdo-cerrado a la derecha-abierto), la publicación alguna vez fue una "publicación caliente".

Dado el registro, ayude a Xiaoming a contar todas las ID de publicaciones que alguna vez fueron "publicaciones calientes".

formato de entrada

La primera línea contiene tres números enteros N, D, K.

Cada una de las siguientes N líneas contiene un registro, incluidos dos números enteros ts e id.

formato de salida

Muestra los ID de las publicaciones activas en orden ascendente.

Una línea por id.

rango de datos

1 ≤ K ≤ norte ≤ 10 5 ,
0 ≤ ts, identificación ≤ 10 5 ,
1 ≤ re ≤ 10000

Muestra de entrada:

7 10 2
0 1
0 10
10 10
10 1
9 1
100 3
100 3

Salida de muestra:

1
3
#include <iostream>
#include <algorithm>
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 1e5 + 10;
int n, d, k;
PII logs[N]; // x存时间,y存id
int cnt[N]; // 用来记录一个id号获得的赞数,表示形式为cnt[id] ++;
bool st[N]; // 记录每个帖子是否是热帖

int main()
{
    
    
    scanf("%d%d%d", &n, &d, &k);
    for (int i = 0; i < n; i ++) scanf("%d%d", &logs[i].x, &logs[i].y);
    
    sort(logs, logs + n); // 按照第一字段ts时间排序
    
    for (int i = 0, j = 0; i < n; i ++)
    {
    
    
        int id = logs[i].y;
        cnt[id] ++; // 记录帖子出现的次数
        
        // 当两个指针跨越的时间超过了d,早期的赞过期了,要减去它的过期赞
        while (logs[i].x -logs[j].x >= d) 
        {
    
    
            cnt[logs[j].y] --;
            j ++; // 要把指针j往后,否则死循环
        }
        if (cnt[id] >= k) st[id] = true;
    }
    for (int i = 0; i <= 100000; i ++) if (st[i]) cout << i << endl;
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/laaa123mmm/article/details/129372819
Recomendado
Clasificación