• Home
  • About
    • 코드좀비 photo

      코드좀비

      An amazing website.

    • Learn More
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

[BOJ] 백준 17297번 Messi Gimossi 코드 C++

29 Jun 2019

Reading time ~2 minutes

문제 정보

백준 BOJ 17297번 Messi Gimossi 문제 링크 : https://www.acmicpc.net/problem/17297 선린인터넷고등학교 제3회 천하제일 코딩대회 예선 E번

문제 풀이

이번 문제는 규칙을 찾아 내는게 가장 핵심인 문제입니다.

우선적으론 글자를 이어 붙여 할 생각은 접는게 좋습니다.

그래서 글자 수를, 피보나치로 만들어 배열에 저장해둡니다.

	pibo.push_back(5);
	pibo.push_back(13);

	while (w < 1073741824) {
		e = w;
		w = w + q+1;
		q = e;
		pibo.push_back(w);
	}

이렇게요

그다음엔 무엇을 해야 하는가?

n 이 만약에 21이라고 생각을 해봅시다.

pibo[0] = 5,

pibo[1] = 13

pibo[2] = 19

pibo[3] = 33

입니다.

n 보다 큰 최초의 pibo 를 구해주면 되는데요

21이라면, pibo[3]이겠죠?

pibo[3] 은 어떻게 만들어질까요?

pibo[2] + pibo[1] 입니다.

구역을 나누자면 [ pibo[i-1]개 / pibo[i-2개 ]

로 나누어 지겠죠.

그럼 이제 pibo[i-1] 개로 기준을 나눕니다.

n 이 이거보다 크냐 작냐로 나누면 되요.

만약에 n이 pibo[i-1] 보다 작다면

[ pibo[i-1] V여기어딘가 / pibo[i-2] ] 안에 있는 겁니다.

그러면 그대로 i만 -1 해서 탐색을 해줍니다.

반대로 pibo[i-1] 보다 크면

[pibo[i-1] / pibo[i-2] 어딘가] 에 있겠죠

그러면 앞에 pibo[i-1] 부분은 볼 필요가 없습니다.

앞에 부분을 버려버리고 pibo[i-2] 부분으로 넘어가 주면 됩니다.

예시를 들어볼께요

pibo[2] = 19 n = 21

n 이 pibo[2]보다 큼으로

n은 pibo[1] 에 속한다고 보고

21 - 19 해주면

pibo[1] 의 2번째 와 같습니다.

그럼 pibo[1] 의 2번째를 출력 해 주면 됩니다.

만약 수가 더 크다면?

반복문을 통해서 아래까지 쭉쭉 내려와 주시면 됩니다.

그러면 간단하게 문제가 해결이 됩니다. !

코드

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main() {
	string b;
	int n;
	int q;
	int w;
	int e;
	int i;
	vector<int> pibo;
	b = "Messi Gimossi";

	q = 5;
	w = 13;
	pibo.push_back(5);
	pibo.push_back(13);

	while (w < 1073741824) {
		e = w;
		w = w + q+1;
		q = e;
		pibo.push_back(w);
	}

	cin >> n;
	i = 0;
	while (pibo[i] < n)
		i++;
	while ( i >= 2) {
		if (n == pibo[i - 1] + 1) {
			n = -1;
			break;
		}
		if (n > pibo[i - 1]) {
			i -= 2;
			n -= pibo[i + 1]+1;
		}
		else
			i -= 1;
	}

	if (n == -1 || n == 6) {
		cout << "Messi Messi Gimossi";
	}
	else {
		cout << b.at(n - 1);
	}

	return 0;
}


백준C++ Share Tweet +1