baekjoon
3078번 좋은 친구
gokimkh
2022. 4. 16. 13:11
https://www.acmicpc.net/problem/3078
3078번: 좋은 친구
첫째 줄에 N과 K가 주어진다. (3 ≤ N ≤ 300,000, 1 ≤ K ≤ N) 다음 N개 줄에는 상근이네 반 학생의 이름이 성적순으로 주어진다. 이름은 알파벳 대문자로 이루어져 있고, 2글자 ~ 20글자이다.
www.acmicpc.net
큐와 슬라이딩 윈도우 기법을 사용하였다.
1. 자기 글자수에 맞게 큐에 넣어준다.
2. 순위가 높은순으로 큐에 들어간다.
3. (제일 나중에 들어온 순위 - 큐 가장 앞에 있는 순위)가 k를 초과하면 가장 앞에 있는 순위를 빼준다. -> 슬라이딩 윈도우 기법
주의해야 할 점은 만약 n = k = 300000이면 쌍이 (299999 * 300000 / 2) 개가 만들어지므로 int 범위를 넘어간다.
#include <bits/stdc++.h>
#define all(v) v.begin(), v.end()
#define INF 2e9
#define F first
#define S second
using namespace std;
typedef long long l;
typedef pair<int,int> p;
typedef tuple<int,int,int> tu;
typedef vector<int> vc;
int main() {
ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
string s;
int n,k;
l ans = 0;
queue<int> q[22];
cin >> n >> k;
for(int i=0;i<n;i++){
cin >> s;
int size = int(s.size());
while(!q[size].empty() && i - q[size].front() > k)
q[size].pop();
ans += int(q[size].size());
q[size].push(i);
}
cout << ans;
}