https://www.acmicpc.net/problem/27468
문제
KSA 학생들은 아래 조건을 만족하는 길이가 인 수열을 좋아한다.
- 1,2,⋯,N이 A에 정확히 한 번씩 등장한다.
- 임의의 인접한 세 수 A_i, A_{i+1}, A_{i+2}에 대해 |A_{i+1}−A_i|=|A_{i+2}−A_{i+1}|×2 또는 |A_{i+1}−A_i|=|A_{i+2}−A_{i+1}|×0.5이다.
정수 N이 주어졌을 때, 조건을 만족하는 수열이 존재하는지 판별하고 있다면 아무거나 찾아보자.
입력
첫 번째 줄에 정수 N이 주어진다.
출력
첫 번째 줄에 조건을 만족하는 수열이 존재한다면 YES, 아니라면 NO를 출력한다.
만약 그러한 수열이 존재한다면, 두 번째 줄에 N개의 정수 A1,A2,⋯,AN출력한다.
정답이 여러 개 존재한다면 아무거나 출력해도 상관없다.
제한
- 3≤N≤2×10^6
서브태스크
번호배점제한
1 | 7 | N≤10 |
2 | 33 | N은 4의 배수 |
3 | 60 | 추가 제약 조건 없음 |
예제 입력 1
4
예제 출력 1
YES
3 1 2 4
예제 입력 2
16
예제 출력 2
YES
1 2 4 8 6 5 7 3 11 15 13 14 16 12 10 9
처음에는 브루트포스로 그냥 찾다보면 수열을 얻을 수 있을 것이라 생각했지만, 일일히 찾다보면 TLE가 날 것 같았다.
그래서 그냥 하나하나 수열을 만들어 보았다.
노드를 연결하는 패턴을 보니 1, 2, 1, 2, ... 혹은 2, 1, 2, 1, ...의 패턴이면 모든 수열을 만들 수 있을 것 같았다.
그래서 패턴을 두개로 나누어 배열을 만들었고, 두 패턴중에 맞는 패턴을 찾아서 배열을 출력하면 된다.
#include <bits/stdc++.h>
using namespace std;
int n;
int c[2020202];
int pattern1[4] = {1,2,-1,2};
int pattern2[4] = {2,-1,2,1};
queue<int> q;
int sol(int pattern[4]){
q.push(1);
for(int i = 0 ; i <= n ; i++) c[i]=0;
bool flag = true;
int i = 1;
for(int j = 0 ; j < n-1 ; j++){
int a = pattern[j%4];
i+=a;
if(i<=n && c[i]==0){
c[i]=1;
q.push(i);
}
else{
return 1;
}
}
return 0;
}
int main(void){
cin>>n;
int res1 = sol(pattern1);
int res2;
if(res1==1){
while(!q.empty()) q.pop();
res2 = sol(pattern2);
}
else{
cout<<"YES\n";
while(!q.empty()){
cout<<q.front()<<" ";
q.pop();
}
return 0;
}
if(res2==1){
cout<<"NO";
}
else{
cout<<"YES\n";
while(!q.empty()){
cout<<q.front()<<" ";
q.pop();
}
return 0;
}
}
사실 NO가 나올 일은 없지만 그래도 예의상 코드를 짜긴 했다.
'백준 알고리즘 풀이 > C, C++' 카테고리의 다른 글
[백준] 25187번 : 고인물이 싫어요 (C++) (0) | 2025.03.29 |
---|---|
[백준] 1082번 : 방 번호 (C++) (0) | 2025.03.17 |
[백준] 9963번 : N - Queen (C++) (0) | 2025.03.11 |
[백준] 17070번 : 파이프 옮기기 1(C++) (0) | 2025.03.10 |
[백준]18429번 :근손실(C++) (0) | 2025.03.09 |