본문 바로가기
[PS] 문제풀이/백준

[ 백준 17822 ] 원판 돌리기 (C++)

by 안산학생 2020. 2. 19.

[문제보기]

 

[해결과정]

 

 1. deque 2차원 배열 생성.

 2. deque에 값 넣기.

 

 3. 문제 입력 받기 (돌릴 내용)

 4. turn 함수 실행 전, x의 배수 만큼 돌릴 수 있도록 반복문 설정 후 turn 진입

  - 만약 시계 방향이라면, 뒤에 것을 앞으로...

  - 만약 반시계 방향이라면, 앞에 것을 뒤로...

 

 5. 같은 숫자 지우기

  - 절대값으로 비교 ! 좌우, 앞뒤, *** 가장 중요한 맨앞, 맨뒤 *** ---> 같은 수라면 음수로 설정

    - 절대값으로 비교하는 이유 : 이미 발견된 수가 있을 수 있으므로...

  - 만약 같은 숫자를 단 한번이라도 지운 적이 있다면 flag 변수 설정

  - 모든 작업 후에, 음수인 숫자를 0으로 변경

 

 6. 만약 같은 숫자가 하나도 없었더라면,

  - deque에 있는 모든 수를 더하고 (***0이 아닌수만!!!) 모든 수의 갯수를 구한뒤 평균을 냄

  - *** 가장 중요한 것은 백준에선 소수점까지 처리한다는 것! 그러므로 double형이 되어야함 ***

  - 평균 값보다 크면 -1, 작으면 +1

   

 

[소스코드]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
    BOJ 17822 - 원판 돌리기
    Created by haejun on 2020/02/19
*/
#include<iostream>
#include<vector>
#include<deque>
#include<math.h>
using namespace std;
const int MAX = 52;
 
deque <int> dq[MAX];
int n, m, t;
 
void turn(int x, int d, int k) {
    for (int i = 0; i < k; i++) {
        int temp;
        if (d == 0) {
            temp = dq[x].back();
            dq[x].pop_back();
            dq[x].push_front(temp);
        }
        else {
            temp = dq[x].front();
            dq[x].pop_front();
            dq[x].push_back(temp);
        }
    }
}
 
void del() {
    // 같은 것 찾기
    bool f = false;
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < m; j++) {
            if (j == m - 1) {
                if (dq[i].front() == 0 || dq[i].back() == 0continue;
                if (abs(dq[i].front()) == abs(dq[i].back())) {
                    if (dq[i][0> 0) dq[i][0= -dq[i][0];
                    if (dq[i][j] > 0) dq[i][j] = -dq[i][j];
                    f = true;
                }
            }
            // 처음과 끝은 좌우만 확인
            else {
                if (dq[i][j] == 0 || dq[i][j + 1== 0continue;
                if (abs(dq[i][j]) == abs(dq[i][j + 1])) {
                    if (dq[i][j] > 0) dq[i][j] = -dq[i][j];
                    if (dq[i][j + 1> 0) dq[i][j + 1= -dq[i][j + 1];
                    f = true;
                }
            }
 
        }
    }
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (dq[i][j] == 0 || dq[i + 1][j] == 0continue;
            if (abs(dq[i][j]) == abs(dq[i + 1][j])) {
                if (dq[i + 1][j] > 0) dq[i + 1][j] = -dq[i + 1][j];
                if (dq[i][j] > 0) dq[i][j] = -dq[i][j];
                f = true;
            }
        }
    }
 
    // 같은 것들을 찾았다면..
    if (f == true) {
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j < m; j++) {
                if (dq[i][j] < 0) dq[i][j] = 0;
            }
        }
    }
    else {
        double sum = 0;
        double cnt = 0;
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j < m; j++) {
                if (dq[i][j] == 0continue;
                sum += dq[i][j];
                cnt++;
            }
        }
        double avg = sum / cnt;
        //cout << avg <<" "<<sum<<"/"<<cnt << endl;
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j < m; j++) {
                if (dq[i][j] == 0continue;
                if (dq[i][j] > avg) dq[i][j] -= 1;
                else if (dq[i][j] < avg) dq[i][j] += 1;
            }
        }
 
    }
 
    //디버깅
    /*
    cout << "\n";
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < m; j++) {
            cout << dq[i][j]<<" ";
        }
        cout << "\n";
    }
    cout << "\n";
    */
}
 
int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
 
    // input
    cin >> n >> m >> t;
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < m; j++) {
            int temp;
            cin >> temp;
            dq[i].push_back(temp);
        }
    }
 
    // turn
    for (int i = 0; i < t; i++) {
        int x, d, k;
        cin >> x >> d >> k;
        // 돌리기
        int temp = x;
        while (true) {
            if (temp > n) break;
            turn(temp, d, k);
            temp = temp + x;
        }
 
        del();
 
        
    }
 
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < m; j++) {
            ans += dq[i][j];
        }
    }
 
    cout << ans << "\n";
 
    return 0;
}
 

[해결 과정 중 실수한 부분]

 이 문제는 재밌게 풀었던 기억이 난다,, (3달 전에)... (3달 전에 진짜 열심히 했었구나...)

 다시 풀어본 결과 1시간 30분이 걸렸다... 이유는, for문을 사용하는데 위에서 i변수를 사용했는데 바로 밑에서 또 i변수를 계속 썼었던 것이다... 전에 풀었던 소스는 함수화 해서, 모듈별로 기능을 작성했는데, 이번에는 함수화 하지않고 계속 쭈욱 풀어서 써서 그런지 이런 실수를 했던 것 같다..

 

 문제 자체는 그렇게 어렵지 않았는데, 이러한 잔실수 때문에, 시간이 많이 허비가 됐다..

 

 근데 정말 신기한것은, 이렇게 큰 실수임에도 불구하고 테스트 케이스는 다맞았다는거 ㅡㅡ...

 

 어제 네이버 코딩테스트에서도 0점이 맞는 소스임에도 불구하고 테스트 케이스는 다 맞았는데, 또 같은 실수를 했다.. 진짜 어제 오늘로, 이러한 실수는 절대 하지 말아야지 다짐한다...!

 

[관련 문제 혹은 비슷한 문제]

 삼성 역량테스트



'[PS] 문제풀이 > 백준' 카테고리의 다른 글

[ 백준 1926 ] 그림 (C++)  (0) 2020.02.24
[ 백준 17472 ] 다리 만들기2 (C++)  (0) 2020.02.22
[ 백준 16234 ] 인구 이동 (C++)  (0) 2020.02.12
[ 백준 1238 ] 파티 (C++)  (0) 2020.02.12
[ 백준 1920 ] 수 찾기 (C++)  (0) 2020.02.03

댓글