Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions 11_투포인터/필수/14503.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// 로봇 청소기
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int dir[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; // 북, 동, 남, 서

// 청소하는 영역의 개수를 구한다.
int cleanRoom(int r, int c, int d, vector<vector<int>> room){
int n = room.size();
int m = room[0].size();
int cnt_clean = 0;

while(true){
// 현재 칸이 청소되지 않은 경우, 청소한다
if (room[r][c] == 0){
cnt_clean++;
room[r][c] = 2;
}

// 현재 칸의 주변 4칸 확인 (현재방향의 반시계 90도 회전 방향부터)
bool moved = false;
for (int i = 0; i < 4; i++){
// 전진 방향 확인
d = (d + 3) % 4;
int nr = r + dir[d][0];
int nc = c + dir[d][1];

if (nr < 0 || nr >= n || nc < 0 || nc >= m){
continue;
}

// 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 있는 경우,
if (room[nr][nc] == 0){
// 바라보는 방향을 기준으로 앞쪽 칸이 청소되지 않은 빈 칸인 경우 한 칸 전진한다.
r = nr;
c = nc;
moved = true;
break;
}
}

// 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 없는 경우,
if (!moved){
// 후진 방향 확인
int nr = r - dir[d][0];
int nc = c - dir[d][1];

if (nr < 0 || nr >= n || nc < 0 || nc >= m){
continue;
}

// 후진할 곳이 벽이 아니면 후진
if (room[nr][nc] != 1) {
r = nr;
c = nc;
} else {
// 후진할 수 없으면 종료
break;
}
}
}

return cnt_clean;
}

int main(){
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);

// 입력
int n, m; // 방의크기 n * m
int r, c; // 처음 로봇청소기 좌표 (r, c)
int d; // 처음에 로봇청소기가 바라보는 뱡향 (0-북, 1-동, 2-남, 3-서)
vector<vector<int>> room; // 각 칸의 상태 (0-빈칸, 1-벽)
int answ; // 로봇청소기가 청소하는 칸의 개수

cin >> n >> m;
cin >> r >> c >> d;
for (int i = 0; i < n; i++){
vector<int> input(m, 0);
for (int j = 0; j < m; j++){
cin >> input[j];
}
room.push_back(input);
}

// 연산
answ = cleanRoom(r, c, d, room);

// 출력
cout << answ << '\n';

return 0;
}
57 changes: 57 additions & 0 deletions 11_투포인터/필수/20922.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// 겹치는 건 싫어
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int MAX_NUM = 100001; // 문제 내 수열 길이 최댓값 조건

// 같은 정수를 k개 이하로 가지는 최장 연속 부분 수열의 길이 구하기
int solution(const vector<int> arr, int k, int n){
// 초기화
int answ = 1; // 시작 시점 길이: 0번째 원소만 포함
int left = 0, right = 1; // 부분 수열의 왼쪽, 오른쪽 포인터. 왼쪽은 포함하고 오른쪽은 포함 안함
vector<int> count(MAX_NUM, 0); // 수열 내 각 숫자의 개수
count[arr[left]]++; // (left = 0)의 해당 원소 개수 증가

// 오른쪽 포인터가 수열 끝에 다다를 때까지
while (right < n){
// right를 오른쪽으로 증가하면서 right번째 숫자를 수열에 추가할 수 있는지 확인
if(count[arr[right]] >= k){ // right번째 숫자의 개수가 k 이상이면 추가 불가능
count[arr[left]]--; // left 숫자를 삭제
left++; // left 오른쪽으로 이동
continue; // 다시 right 추가 가능한지 확인
}

// right 숫자를 수열에 추가 가능한 경우
count[arr[right]]++; // right 숫자를 수열에 추가
right++; // right 오른쪽으로 이동
answ = max(answ, right - left); // 최대값 갱신
}

return answ;
}

int main(){
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);

int n; // n: 주어진 수열 길이
int k; // k: 같은 정수 포함 가능 개수
vector<int> arr; // arr: 수열
int answ; // answ: 같은 정수를 k개 이하로 포함한 최장 연속 부분 수열의 길이

// 입력
cin >> n >> k;
arr.assign(n, 0);
for (int i = 0; i < n; i++){
cin >> arr[i];
}

// 연산
answ = solution(arr, k, n);

// 출력
cout << answ << '\n';

return 0;
}
67 changes: 67 additions & 0 deletions 11_투포인터/필수/2531.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// 회전 초밥
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// 슬라이딩 윈도우로 주어진 회전 초밥 벨트에서 먹을 수 있는 초밥의 가짓수의 최댓값을 반환
int findMaxEat(int n, int k, int c, const vector<int> &arr){
vector<int> count(3001, 0); // 초밥 종류별 카운트 배열, 초밥의 최대 종류 수만큼 크기 지정
int max_cnt = 0, current_cnt = 0;

// 초기화: 첫 번째 윈도우
for (int i = 0; i < k; i++) {
if (count[arr[i]] == 0) current_cnt++;
count[arr[i]]++;
}

// 쿠폰 초밥 추가
if (count[c] == 0) current_cnt++;
count[c]++;
max_cnt = current_cnt;

// 슬라이딩 윈도우
for (int i = 0; i < n; i++) {
int remove_idx = arr[i];
int add_idx = arr[(i + k) % n];

// 이전 초밥 제거
count[remove_idx]--;
if (count[remove_idx] == 0) current_cnt--;

// 새로운 초밥 추가
if (count[add_idx] == 0) current_cnt++;
count[add_idx]++;

// 최대 가짓수 업데이트
max_cnt = max(max_cnt, current_cnt);
}

return max_cnt;
}

int main(){
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);

// 회전 초밥 벨트에 놓인 접시의 수 n, 초밥의 가짓수 d,
// 연속해서 먹는 접시의 수 k, 쿠폰 번호 c
int n, d, k, c;
vector<int> arr; // 벨트 위에 있는 초밥들
int answ; // 주어진 회전 초밥 벨트에서 먹을 수 있는 초밥의 가짓수의 최댓값

// 입력
cin >> n >> d >> k >> c;
arr.assign(n, 0);
for (int i=0; i<n; i++){
cin >> arr[i];
}

// 연산
answ = findMaxEat(n, k, c, arr);

// 출력
cout << answ << '\n';

return 0;
}