본문 바로가기

백준

백준2635 - 수 이어가기

https://www.acmicpc.net/problem/2635

 

2635번: 수 이어가기

첫 번째 수가 주어진다. 이 수는 30,000 보다 같거나 작은 양의 정수이다.

www.acmicpc.net

문제 풀 때는 몰랐는데 수열이 x와 k의 계수가 피보나치 꼴로 나온다. x는 0부터 시작한다고 가정을 하고 짝수번째 수열이면 -가 붙고 홀수번째 수열이면 +가 붙는다. k는 x와 반대로 부호가 붙는다. 우선 수가 30000까지로 작기 때문에 임의로 50개의 계수를 구한 뒤 반복문을 돌렸다.

 

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main() {
	//문제는 ax + bk >= 0을 만족하는 x를 찾고 그 x중에서 최고로 많은 수열을 나타낼 수 있는 수를 찾아서 수열을 적는것.
	int k; //주어진 k이하의 수를 찾기 위하여 설정한 k 
	int big = -1; //가장 많은 수열 인자가 있을 때의 수열의 총 인자 갯수
	int cnt = 0; //현재 몇 번째 수열 인자가 생겼는지 구하는 변수
	vector<int> a; //x의 계수
	vector<int> b; //k의 계수
	vector<int> temp; //반복문의 과정을 임시로 담는 변수
	vector<int> ans; //현재 수가 최대의 수열인자를 가질 때 그 기록을 담는 변수 

	cin >> k;

	//x의 계수를 구하기, 초항으로 0, 둘째항으로 1을 넣는다. 그 다음 짝수 번째이면 음수, 홀수 번째이면 양수로 선언한다.
	a.push_back(0); 
	a.push_back(1);
	for (int i = 2; i < 50; i++) {
		if (i % 2 == 0) {
			a.push_back(-(abs(a[i - 2]) + abs(a[i - 1])));
		}
		else {
			a.push_back((abs(a[i - 2]) + abs(a[i - 1])));
		}
	}

	//k의 계수를 구하기, 초항으로 1, 둘째항으로 0을 넣는다. 그 다음 짝수 번째이면 양수, 홀수 번째이면 음수로 선언한다.
	b.push_back(1);
	b.push_back(0);
	for (int i = 2; i < 50; i++) {
		if (i % 2 == 0) {
			b.push_back((abs(b[i - 2]) + abs(b[i - 1])));
		}
		else {
			b.push_back(-(abs(b[i - 2]) + abs(b[i - 1])));
		}
	}

	//최대의 경우의 수를 찾는 과정, 관계식의 의거하여 풀었다.
	for (int i = 1; i <= k; i++) {
		for (int j = 0; j < a.size(); j++) {
			if (a[j] * i + b[j] * k < 0) {
				break;
			}
			temp.push_back(a[j] * i + b[j] * k);
			cnt++;
		}
		if (big < cnt) {
			big = cnt;
			ans = temp;
		}
		cnt = 0;
		temp.clear();
	}

	//결과 출력
	cout << big << '\n';
	for (int i = 0; i < ans.size(); i++) {
		cout << ans[i] << ' ';
	}
}

'백준' 카테고리의 다른 글

백준10164 - 격자상의 경로  (0) 2019.11.20
백준13423 - Three Dots  (0) 2019.11.14
백준2225 - 합분해  (0) 2019.10.31
백준13413 - 오셀로 재배치  (0) 2019.10.29
백준2436 - 공약수  (0) 2019.10.27