알고리즘 풀이/백준(Boj)

백준(BOJ) 17088번 등차수열 변환

100win10 2020. 1. 12. 13:47

문제 : https://www.acmicpc.net/problem/17088

 

17088번: 등차수열 변환

크기가 N인 수열 A = [A1, A2, ..., AN]이 있을 때, 모든 1 ≤ i < N에 대해서, Ai+1-Ai가 모두 일치하면 등차수열이라고 한다. 예를 들어, [3], [6, 6, 6], [2, 8, 14, 20], [6, 4, 2]는 등차수열이고, [4, 5, 4], [6, 3, 1]은 등차수열이 아니다. 수열 B = [B1, B2, ..., BN]을 등차수열로 변환하려고 한다. 각각의 수에는 연산을 최대 한 번 적용할 수 있다. 연산은 두 가

www.acmicpc.net

 

풀이 :

 

모든 경우를 다해 보기에는 N이 10만이기 때문에 3^10만으로 도저히 불가능하다.

 

따라서 등차수열의 성질을 이용해서 a[0] 과 a [1]만 각각 -1,0,1로 바꿔서 계산해보자

 

그때 diff 는 a [1] - a [0]이고 등차수열을 했을 때의 값과 a [2] ~ a [n]까지 비교해가면서 

 

cnt를 +해주고 ans와 최소값을 비교하자.

 

코드 ( C++ )

 

#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; ++i)
cin >> a[i];
if (n == 1) {
cout << 0 << "\n";
return 0;
}
int ans = -1;
for(int d1 = -1; d1 <=1; ++d1)
for (int d2 = -1; d2 <= 1; ++d2)
{
int cnt = 0;
if (d1 != 0) cnt += 1;
if (d2 != 0) cnt += 1;
int first = a[0] + d1;
int second = a[1] + d2;
int diff = second - first;
bool ok = false;
int cand = second;
//등차수열의 성질 이용
for (int i = 2; i < n; ++i) {
cand += diff;
//같으면 그냥 넘어간다
if (a[i] == cand) continue;
if (a[i] + 1 == cand)
cnt += 1;
else if (a[i] - 1 == cand)
cnt += 1;
// +1이나 -1해서 만들 수 없을때
else {
ok = true;
break;
}
}
if (!ok) {
if (ans == -1 || cnt < ans)
ans = cnt;
}
}
cout << ans << "\n";
return 0;
}
view raw .cpp hosted with ❤ by GitHub