halang-log
💡 PS

[BOJ] 2938 3으로 나누어 떨어지지 않는 배열

date
Feb 26, 2022
slug
boj-2938
author
status
Public
tags
PS
summary
3으로 나누어 떨어지지 않는 배열에 대한 풀이입니다.
type
Post
thumbnail
category
💡 PS
updatedAt
Aug 3, 2023 09:00 AM
언어

문제

풀이

우선 3으로 나누어 떨어지지 않게 배열을 만들 수 없는 경우를 생각해보면 다음과 같은 상황이 있을 것이다. cf) 참고로, 0~2는 해당수 % 3을 한 값을 의미한다.
  1. 0이 연속으로 나올 수 밖에 없을 때
  1. 1과 2가 붙을 수 밖에 없을 때
첫번째의 경우, 0의 개수가 1과 2의 개수를 합친 것보다 두개 이상 많을 때이다. 두번째의 경우, 1과 2는 있는데 0이 없는 경우이다.
나는 다음과 같은 방식으로 문제를 풀었다.
  1. 1의 수(3으로 나누었을 때 나머지가 1)를 순서대로 anspush한다.
  1. 만약, 1과 2가 모두 있다면 두 수 사이에 0(3으로 나누었을 때 나머지가 0)이 반드시 필요하므로 push해준다.
  1. 2의 수(3으로 나누었을 때 나머지가 2) 순서대로 anspush한다.
  1. 0의 수가 남아있다면 넣을 수 있는 공간에 알맞게 넣는다.

코드

#include <cstdio> #include <vector> using namespace std; int n; int arr[10000]; vector<int> v_1, v_2, v_0, ans; void go() { int ix = v_0.size()-1; for(int i : v_1) ans.push_back(i); if (v_1.size() and v_2.size()) { ans.push_back(v_0[ix]); ix--; } for(int i : v_2) ans.push_back(i); for(int i = 0; i < ans.size(); i++) { if (ix >= 0 and arr[ans[i]] % 3) { if (i > 0 and arr[ans[i-1]] % 3) printf("%d ", arr[v_0[ix--]]); else if (i == 0) printf("%d ", arr[v_0[ix--]]); } printf("%d ", arr[ans[i]]); } if (ix == 0) printf("%d", arr[v_0[0]]); } int main() { scanf("%d", &n); for(int i = 0; i < n; i++) { scanf("%d", &arr[i]); if (arr[i] % 3 == 0) v_0.push_back(i); else if (arr[i] % 3 == 1) v_1.push_back(i); else v_2.push_back(i); } if (int(v_0.size() - v_1.size() - v_2.size()) > 1) { printf("-1"); return 0; } else if (v_0.size() == 0 and v_1.size() > 0 and v_2.size() > 0) { printf("-1"); return 0; } go(); }