Codeforces Round #750 (Div. 2)-D. Vupsen, Pupsen and 0

falconlee236

·

2021. 12. 13. 19:29

반응형

문제 설명

카파와 수아는 정수 배열을 선물받았다. 카파는 숫자 0을 싫어하기 때문에 카파는 배열에서 0을 다 버려버렸다. 그 결과 길아기 n인 배열 a를 얻었다.

수아는 반대로 숫자 0을 좋아하기 때문에 0을 제외한 숫자로만 이루어져 있는 배열을 보고 화가 났다. 수아를 응원하기 위해서 카파는 길아가 n인 또 다른 배열 b를 생각해 냈다. 이 배열은 i=1naibi=0 을 만족한다. 카파는 숫자 0을 싫어하기 때문에 배열 b는 숫자 0이 포함하면 안된다. 또한 숫자는 반드시 크면 안된다. 따라서 배열 b 원소의 절대값의 총합이 109를 넘어가면 안된다. 위의 조건을 만족하는 배열 b를 찾을 수 있도록 도와주자.

Input
첫번째 줄에는 테스트 케이스의 개수를 나타내는 정수 t(1t100) 이 주어진다.

각 테스트케이스의 첫번째 줄에는 배열의 길이 n(2n105) 가 주어진다.

각 테스트케이스의 두번째 줄에는 배열 a의 원소인 n개 정수 a1,a2,...,an(104ai104,ai0) 가 주어진다.

Output
각 테스트 케이스마다 원소 nb1,b2,...,bn(|b1|+|b2|+...+|bn|109,bi0,i=1naibi=0) 로 이루어진 배열 b를 출력한다.

Example
input
3
2
5 5
5
5 -2 10 -9 4
7
1 2 3 4 5 6 7

output
1 -1
-1 5 1 -1 -1
-10 2 2 -3 5 -1 -1

문제 접근

사용한 알고리즘: 수학, 구성적
걸린 시간 : 00:10
C번에서 너무 시간을 끌어서 이 문제를 깊이있게 생각 할 수 가 없었던 것 같다. C번을 버리고 바로 이 문제를 1시간 반동안 생각했으면 풀었을 수도 있을 것 같다. 이 문제는 구성적 알고리즘을 사용하는 전형적인 문제인 것 같고 몇가지 테스트 케이스를 직접 만들어서 생각해보면 규칙성이 보인다.

먼저 배열의 길이가 짝수인 경우 쉽게 풀 수 있다. 만약 배열 a[1,2,3,4] 로 이루어져 있다고 하면 배열 b는 다음과 같이 만들 수 있다. 각 배열을 2개씩 묶은 수를 (a,b) 라고 하면 (b,a)이런 식으로 배열을 구성하면 배열의 길이가 짝수 인경우 무조건 b를 구할 수 있다. 따라서 b[2,1,4,3] 으로 만들면 된다.

그렇다면 배열의 길이가 홀수인 경우 어떻게 풀까? 일단 배열에서 맨 앞에 있는 원소 3개를 빼면 뒤에 남아있는 배열은 짝수 길이 배열이기 때문에 위에서 언급한 배열의 길이가 짝수인 경우 배열을 구성하는 방법을 통해서 쉽게 구할 수 있다. 그러면 남아있는 숫자 3개로 어떻게 0을 만들 수 있을까? 배열 a의 원소를 a1,a2,a3이라고 하고, 배열 b의 원소를 x,y,z라고 하자. 그러면 우리가 풀어야 할 식은 a1x+a2y+a3z=0 이다. 살짝 생각하기 어려울 수 있는데, x=a3,y=a3,z=(a1+a2)라고 하면 해를 구했다. 그런데 여기서 z가 살짝 문제다. 배열의 원소는 0이 되면 안되는데, a2=a1이면 z0이 되기 때문에 답이 아니다. 그렇기 때문에 z=(a1+a2)인 경우, y=(a1+a3) 인경우 x=(a2+a3) 인경우 모두를 고려해서 답을 구하면 된다.

맨 마지막에 있는 조건은 무조건 맞출 수 있을까? 일단 모든 원소가 104로 이루어져 있는 배열의 길이가 105인 경우를 생각해보자. 배열의 길이가 짝수이기 때문에 총 배열의 합은 104105=109 이기 때문에 조건을 만족한다.

배열의 길이가 1051인 경우는 어떨까? 일단 이 배열에서 원소 3개를 빼고 남은 것은 다 절댓값이 104인 원소로 만들 수 있기 때문에 이 합은 (1054)104)=1094104) 이다.
그러면 나머지 3개의 원소는 어떻게 될까? 해는 각각 104,104,(104+104) 이기 때문에 총 절댓값의 합은 4104 이다. 즉 이 모든 값을 더하면 1094104+4104=109 이므로 조건을 만족한다.

정답 코드

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int t; cin >> t;
    while(t--){
        int n; cin >> n;
        int a[n];
        for(int& i : a) cin >> i;
        if(n & 1){
            if(a[0] + a[1]) cout << -a[2] << " " << -a[2] << " " << a[0] + a[1] << " ";
            else if(a[1] + a[2]) cout << a[1] + a[2] << " " << -a[0] << " " << -a[0] << " ";
            else cout << -a[1] << " " << a[0] + a[2] << " " << -a[1] << " ";
            for(int i = 3; i < n; i+=2)  cout << a[i + 1] << " " << -a[i] << " ";
        }else{
            for(int i = 0; i < n; i+=2)  cout << a[i + 1] << " " << -a[i] << " ";
        }
        cout << "\n";
    }
    return 0;
}
반응형