https://www.acmicpc.net/problem/5527
처음에 예제를 보고
같은 전구가 반복되는 pos부터
같은 전구가 또 반복되는 pos -1까지 반전시키면 된다고 생각했습니다.
예제의
1 1 0 0 1 0 1 1 1 0
의 예제에서
처음 1 1(pos 0, 1)이 반복됩니다.
그래서 pos = 1 부터 그 다음에 0 0 이 반복되기 때문에 pos - 1까지의 구간을 반전시키면
1 0 1 0 1 0 1 1 1 0
7이 됩니다.
그 다음 다시 원상 복귀!
1 1 0 0 1 0 1 1 1 0에서
0 0 구간 (위에서 찾은 pos 값 즉.. 3!!!!! 인덱스를 말하는 것)
3부터 시작해서
또 반복되는 구간은
1 1 1
즉 인덱스(pos) 7입니다. 그럼 pos - 1까지 반전을 시켜야하므로
1 1 0 1 0 1 0 1 1 0
7이 됩니다.
마지막으로
1 1 1 구간에서 반복이 연속되므로 1 0 1을 바꿔주는 경우가 있습니다.
1 1 0 0 1 0 1 0 1 0
이것또한 7입니다.
즉 정답은 7입니다!!!!!!!
근데... 이렇게 푸니까 시간 초과..ㅠㅠㅠㅠㅠ
반전시키는 구간 길이가 n이면 n만큼의 시간이 걸릴테고..
구간을 찾는 것도 시간이 걸리고...
여러가지 이유로 시간이 초과됩니다...
n의 시간으로 해결할 수 있어야 할 것 같은데 방법이 잘 떠오르지 않았습니다.
문제의 해결 방법은
전구를 세 구간으로 나누는 것입니다.
이게 무슨 말이냐면
반전 시키는 구간을 O
아닌 구간을 X로 치면
O X X
X O X
X X O
로 구간을 나누면 된다는 말입니다.
구간을 나누는 기준은 같은 전구가 반복되는 pos입니다.
1 1 0 0 1 0 1 1 1 0
이 예제에서는 위에서 설명한 구간이겠지요.
이렇게 해서
배열에 같은 전구가 나올 때 까지의 번갈아가는 패턴의 값을 저장합니다.!
a[0] = 1;(인덱스 0에서 0구간)
a[1] = 2;(인덱스 1에서 2구간)
a[2] = 4;(인덱스 3에서 6구간)
a[3] = 1;(인덱스 7에서 7구간)
a[4] = 2;(인덱스 8에서 9구간)
이렇게 다섯개의 구간이 생성됩니다.
이 5개의 구간 중 연속된 3개를 더하면 최대 번갈아가는 패턴의 값이 나오겠지요!
아래는 정답 코드입니다.
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 | #include <cstdio> #include <cstdlib> #include <cmath> #include <string.h> #include <queue> #include <iostream> #include <algorithm> #include <vector> #include <functional> #include <stack> #define ll long long #define INF 987654321 #define MOD 1000000 #define MAX_SIZE 100000 using namespace std; int a[MAX_SIZE]; int n; int main() { scanf("%d", &n); int before = -1; int pos = 1; for (int i = 0; i < n; i++) { int t; scanf("%d", &t); if (before == t) pos++; a[pos]++; before = t; } int ret = 0; for (int i = 1; i <= pos; i++) { ret = max(ret, a[i - 1] + a[i] + a[i + 1]); } printf("%d", ret); return 0; } | cs |
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 | #include <cstdio> #include <cstdlib> #include <cmath> #include <string.h> #include <queue> #include <iostream> #include <algorithm> #include <vector> #include <functional> #include <stack> #define ll long long #define INF 987654321 #define MOD 1000000 #define MAX_SIZE 100000 using namespace std; bool a[MAX_SIZE]; int n; int cnt(int start, int end) { int before = -1; int ret = 0; int tmp = 0; bool flag = 0; for (int i = 0; i < n; i++) { if (start <= i && i <= end) { a[i] = !a[i]; flag = 1; } if (before != a[i]) tmp++; else ret = max(ret, tmp), tmp = 1; before = a[i]; if (flag) { flag = 0; a[i] = !a[i]; } } return ret; } int f(int pos, int before) { int i; for (i = pos + 1; i < n; i++) { if (before == a[i]) { break; } before = a[i]; } return cnt(pos, i - 1); } int main() { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", a + i); int before = -1; int ret = cnt(-1, -1); for (int i = 0; i < n; i++) { if (before == a[i]) { ret = max(ret, f(i, a[i])); } before = a[i]; } printf("%d", ret); return 0; } | cs |
'알고리즘 > 구현' 카테고리의 다른 글
[10986] 나머지 합 (0) | 2017.07.24 |
---|---|
[3474] 교수가 된 현우 (0) | 2017.07.13 |
[14499] 주사위 굴리기 (0) | 2017.04.16 |
[5624] 좋은 수 (0) | 2017.04.06 |
[3190] 뱀 (0) | 2017.04.05 |