Plite
전자오락 공방
Plite
전체 방문자
오늘
어제
  • 분류 전체보기 (274)
    • 프로젝트 (18)
      • 완성 프로젝트 (3)
      • 프로젝트 진행 내역 (15)
    • 공부 및 정리 (241)
      • 백준 코드 (222)
      • C++ (8)
      • DirectX (2)
      • Unreal Engine (6)
      • 프로그래밍 패턴 (3)
    • 기타 (12)
      • 기타 주저리 (10)
    • 게임과 취미 (1)
    • 대문 (1)

블로그 메뉴

  • 홈
  • 프로젝트
  • 취미, 일상
  • 백준 프로필

공지사항

  • [Read Me]
  • 제 블로그에 방문하신 것을 환영합니다.

인기 글

태그

  • 스택
  • 구현
  • 그래프
  • 최소 스패닝 트리
  • KMP
  • 수학
  • 위상 정렬
  • 정렬
  • 트라이
  • 동적계획법
  • 백트래킹
  • 기하
  • 백준
  • 문자열
  • 조합론
  • 트리
  • C++
  • 세그먼트 트리
  • 이분탐색
  • SCC
  • 투포인터
  • 정수론
  • 분할정복
  • 브루트포스
  • 유니온 파인드
  • LCA
  • 큐
  • 누적합
  • 우선순위큐
  • UC++

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Plite

전자오락 공방

[C++]백준 - 1655번 문제
공부 및 정리/백준 코드

[C++]백준 - 1655번 문제

2021. 8. 25. 16:14

1655번: 가운데를 말해요 (acmicpc.net)

 

1655번: 가운데를 말해요

첫째 줄에는 수빈이가 외치는 정수의 개수 N이 주어진다. N은 1보다 크거나 같고, 100,000보다 작거나 같은 자연수이다. 그 다음 N줄에 걸쳐서 수빈이가 외치는 정수가 차례대로 주어진다. 정수는 -1

www.acmicpc.net

 

1655번 : 가운데를 말해요


수빈이는 동생에게 "가운데를 말해요" 게임을 가르쳐주고 있다. 수빈이가 정수를 하나씩 외칠때마다 동생은 지금까지 수빈이가 말한 수 중에서 중간값을 말해야 한다. 만약, 그동안 수빈이가 외친 수의 개수가 짝수개라면 중간에 있는 두 수 중에서 작은 수를 말해야 한다.

예를 들어 수빈이가 동생에게 1, 5, 2, 10, -99, 7, 5를 순서대로 외쳤다고 하면, 동생은 1, 1, 2, 2, 2, 2, 5를 차례대로 말해야 한다. 수빈이가 외치는 수가 주어졌을 때, 동생이 말해야 하는 수를 구하는 프로그램을 작성하시오.

 

입력


첫째 줄에는 수빈이가 외치는 정수의 개수 N이 주어진다. N은 1보다 크거나 같고, 100,000보다 작거나 같은 자연수이다. 그 다음 N줄에 걸쳐서 수빈이가 외치는 정수가 차례대로 주어진다. 정수는 -10,000보다 크거나 같고, 10,000보다 작거나 같다.

 

 

출력


한 줄에 하나씩 N줄에 걸쳐 수빈이의 동생이 말해야하는 수를 순서대로 출력한다.

 


 

생각해 볼 점


그림으로 보면 쉽습니다.

 

위와 같은 형태로 힙을 2개 구현해 봅시다.

 

짝수개의  수가 존재하면 작은 수를 반환할 것이기 때문에,

 

답은 항상 좌측(최대)힙의 top을 뽑아서 쓸 것입니다.

 

첫 입력을 좌측 힙에 집어넣고, 그 후부터는

 

양쪽 힙의 size를 가지고 시작하여 입력을 받을 것입니다.

 

입력을 받을 때 두 가지 경우의 수가 있는데,

 

1. 왼쪽 힙의 top보다 크다.

 

 

예를 들어 3을 받으면, 1보다 3이 크므로, 오른쪽 힙에 집어넣습니다.

 

2. 왼쪽 힙보다 작다.

 

왼쪽 힙에 집어넣습니다.

 

입력이 끝나면, 확인 작업을 해야합니다.

 

왼쪽 힙과 오른쪽 힙의 size 차이가 많이 난다면, 가운데 값을 정확히 구할 수 없습니다.

 

위와 같이 왼쪽 힙이 오른쪽 힙의 size보다 2 이상 클 경우,

 

위와 같이 왼쪽 힙의 top을 오른쪽 힙에 push 해줍니다.

 

반대로 오른쪽 힙이 왼쪽힙의 size보다 클 경우에도 오른쪽 힙의 top을 왼쪽 힙에 넣어주면 됩니다.

 

코드


#include <iostream>
#include <queue>
using namespace std;

int main() 
{
	int N;
	cin >> N;
	priority_queue<int> pq_left;       //맥스 힙, top이 항상 가운데 값임
	priority_queue<int, vector<int>, greater<int>> pq_right;    //최소 힙
	
	
	int input;
	scanf("%d", &input);
	pq_left.push(input);
	
	pair<int, int> size = make_pair(1, 0);  //<왼쪽 size, 우측 size>
	printf("%d\n", input);
	
	for(int i = 1; i < N; i++)
	{
	    int input;
	   scanf("%d", &input);
	    
	    int size_gap = size.first - size.second;
	
	    if(input < pq_left.top())
	    {
	        size_gap++;
	        pq_left.push(input);
	        
	        //왼쪽힙이 너무 많으면 우측 힙으로 옮김
	        if(1 < size_gap || size_gap < 0) 
	        {
	            pq_right.push(pq_left.top());
	            pq_left.pop();
	            size.second++;
	        }
	        else size.first++;
	    }
	    else 
	    {
	        pq_right.push(input);
	        size_gap--;
	        
	        //우측 힙이 너무 많으면 왼쪽 힙으로 옮김
	        if(size_gap != 0) 
	        {
	            pq_left.push(pq_right.top());
	            pq_right.pop();
	            size.first++;
	        }
	        else size.second++;
	    }
	    
	    printf("%d\n", pq_left.top());
	}
	
	return 0;
}

 

그 외


 

저작자표시 (새창열림)

'공부 및 정리 > 백준 코드' 카테고리의 다른 글

[C++]백준 - 9370번 문제  (0) 2021.08.25
[C++]백준 - 1504번 문제  (0) 2021.08.25
[C++]백준 - 11286번 문제  (0) 2021.08.22
[C++]백준 - 1927번 문제  (0) 2021.08.22
[C++]백준 - 11279번 문제  (0) 2021.08.17
    '공부 및 정리/백준 코드' 카테고리의 다른 글
    • [C++]백준 - 9370번 문제
    • [C++]백준 - 1504번 문제
    • [C++]백준 - 11286번 문제
    • [C++]백준 - 1927번 문제
    Plite
    Plite
    개발 일지, 게임 이야기 등을 적어두는 공간입니다.

    티스토리툴바