반응형

https://www.acmicpc.net/problem/17779

 

17779번: 게리맨더링 2

재현시의 시장 구재현은 지난 몇 년간 게리맨더링을 통해서 자신의 당에게 유리하게 선거구를 획정했다. 견제할 권력이 없어진 구재현은 권력을 매우 부당하게 행사했고, 심지어는 시의 이름

www.acmicpc.net

 

 

[ 문제풀이 ]

 

1. 5구역을 정합니다.

 

2. 1-4구역을 규칙에 따라 나눕니다.

 

3. 각 구역의 인구를 구해 최댓값과 최솟값의 차를 구합니다.

 

4. 차의 최솟값을 ans에 저장합니다.

 

[ 소스코드 ]

 

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
152
153
154
155
156
157
158
159
160
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
 
using namespace std;
 
int N;
int arr[20][20];
int temp[20][20];
int d[2];
int y, x;
int dy[4= { -1,1,0,0 };
int dx[4= { 0,0,-1,1 };
int population;
int ans = 987654321;
 
int bfs(int num)    //1 ~ 4구역 표시
{
    queue<pair<intint>> q;
    int cury, curx;
    if (num == 1) {
        cury = 0;
        curx = 0;
    }
    else if (num == 2) {
        curx = N - 1;
        cury = 0;
    }
    else if (num == 3) {
        curx = 0;
        cury = N - 1;
    }
    else {
        curx = N - 1;
        cury = N - 1;
    }
    int ret = arr[cury][curx];
    temp[cury][curx] = num;
    q.push({ cury,curx });
 
    while (!q.empty())
    {
        int curY = q.front().first;
        int curX = q.front().second;
        q.pop();
 
        for (int i = 0; i < 4; i++) {
            int yy = curY + dy[i];
            int xx = curX + dx[i];
            if (yy >= 0 && yy < N && xx >= 0 && xx < N) {
                if (temp[yy][xx] == 0) {
                    if (num == 1) {
                        if (yy >= 0 && yy < y && xx >= 0 && xx <= x + d[0]) {
                            temp[yy][xx] = 1;
                            ret += arr[yy][xx];
                            q.push({ yy,xx });
                        }
                    }
                    else if (num == 2) {
                        if (yy >= 0 && yy <= y - d[0+ d[1&& xx > x + d[0&& xx <= N - 1) {
                            temp[yy][xx] = 2;
                            ret += arr[yy][xx];
                            q.push({ yy,xx });
                        }
                    }
                    else if (num == 3) {
                        if (yy >= y && yy <= N - 1 && xx >= 0 && xx < x + d[1]) {
                            temp[yy][xx] = 3;
                            ret += arr[yy][xx];
                            q.push({ yy,xx });
                        }
                    }
                    else {
                        if (yy > y - d[0+ d[1&& yy <= N - 1 && xx >= x + d[1&& xx <= N - 1) {
                            temp[yy][xx] = 4;
                            ret += arr[yy][xx];
                            q.push({ yy,xx });
                        }
                    }
                }
            }
        }
    }
 
    return ret;
}
 
int setMap()    //5구역 표시
{
    for (int i = 0; i <= d[0]; i++) {
        int y1 = y - i;
        int x1 = x + i;
        int y2 = y + d[1- i;
        int x2 = x + d[1+ i;
        temp[y1][x1] = 5;
        temp[y2][x2] = 5;
    }
 
    for (int i = 0; i <= d[1]; i++) {
        int y1 = y + i;
        int x1 = x + i;
        int y2 = y - d[0+ i;
        int x2 = x + d[0+ i;
        temp[y1][x1] = 5;
        temp[y2][x2] = 5;
    }
 
    int pop[6= { 0 };
    pop[5= population;
    for (int i = 1; i <= 4; i++) {    //각 구역별 인구수 구하기
        pop[i] = bfs(i);
        pop[5-= pop[i];
    }
 
    sort(poppop + 6);
    int ret = pop[5- pop[1];
 
    return ret;
}
 
void dfs(int level)
{
    if (level == 2) {
        if (x + d[0+ d[1>= N || y + d[1>= N || y - d[0< 0return;
        memset(temp, 0sizeof(temp));
        int ret = min(ans, setMap());
        if (ret < ans) {    //최솟값 ans에 저장
            ans = ret;
        }
        return;
    }
 
    for (int i = 1; i <= N; i++) {    //d1, d2의 조합
        d[level] = i;
        dfs(level + 1);
    }
}
 
int main()
{
    scanf("%d"&N);
 
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            scanf("%d"&arr[i][j]);
            population += arr[i][j];
        }
    }
 
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            y = i;
            x = j;
            dfs(0);
        }
    }
 
    printf("%d", ans);
}
cs
반응형
반응형

https://www.acmicpc.net/problem/5373

 

5373번: 큐빙

각 테스트 케이스에 대해서 큐브를 모두 돌린 후의 윗 면의 색상을 출력한다. 첫 번째 줄에는 뒷 면과 접하는 칸의 색을 출력하고, 두 번째, 세 번째 줄은 순서대로 출력하면 된다. 흰색은 w, 노란

www.acmicpc.net

 

 

[ 문제풀이 ]

 

1. 매 테스트 케이스마다 큐브를 초기화시켜줍니다.

 

2. 해당 면을 회전시키면 마주 보는 면을 제외하고 모든 면이 바뀌므로 갱신시켜줍니다.

 

3. 변경된 상태를 저장해줍니다.

 

4. 회전이 끝나면 윗면을 출력해줍니다.

 

위의 2번 과정에서 해당 면을 회전시킬 때 면과 이어진 면도 바뀌지만 해당 면도 회전한다는 것을 생각해야 합니다.

 

[ 소스코드 ]

 

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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#include<iostream>
#include<string>
 
using namespace std;
 
void turn(char a, string side[3])    //면 회전
{
    string temp[3= {
        "aaa","bbb","ccc"
    };
    if (a == '+') {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                temp[j][2 - i] = side[i][j];
            }
        }
    }
    else {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                temp[i][j] = side[j][2 - i];
            }
        }
    }
 
    for (int i = 0; i < 3; i++) {
        side[i] = temp[i];
    }
}
 
void change(char* input, string cube[][3])
{
    if (input[0== 'U') {        //윗 면
        string temp = cube[3][0];
        if (input[1== '-') {
            turn('-', cube[0]);
            cube[3][0= cube[5][0];
            cube[5][0= cube[2][0];
            cube[2][0= cube[4][0];
            cube[4][0= temp;
        }
        else {
            turn('+', cube[0]);
            cube[3][0= cube[4][0];
            cube[4][0= cube[2][0];
            cube[2][0= cube[5][0];
            cube[5][0= temp;
        }
    }
    else if (input[0== 'D') {        //아랫 면
        string temp = cube[3][2];
        if (input[1== '-') {
            turn('-', cube[1]);
            cube[3][2= cube[4][2];
            cube[4][2= cube[2][2];
            cube[2][2= cube[5][2];
            cube[5][2= temp;
        }
        else {
            turn('+', cube[1]);
            cube[3][2= cube[5][2];
            cube[5][2= cube[2][2];
            cube[2][2= cube[4][2];
            cube[4][2= temp;
        }
    }
    else if (input[0== 'F') {    //앞 면
        string temp = cube[0][2];
        if (input[1== '-') {
            turn('-', cube[2]);
            for (int i = 0; i < 3; i++) {
                cube[0][2][i] = cube[5][i][0];
                cube[5][i][0= cube[1][2][i];
                cube[1][2][i] = cube[4][2 - i][2];
                cube[4][2 - i][2= temp[i];
            }
        }
        else {
            turn('+', cube[2]);
            for (int i = 0; i < 3; i++) {
                cube[0][2][i] = cube[4][2 - i][2];
                cube[4][2 - i][2= cube[1][2][i];
                cube[1][2][i] = cube[5][i][0];
                cube[5][i][0= temp[i];
            }
        }
    }
    else if (input[0== 'B') {    //뒷 면
        string temp = cube[0][0];
        if (input[1== '-') {
            turn('-', cube[3]);
            for (int i = 0; i < 3; i++) {
                cube[0][0][i] = cube[4][2 - i][0];
                cube[4][2 - i][0= cube[1][0][i];
                cube[1][0][i] = cube[5][i][2];
                cube[5][i][2= temp[i];
            }
        }
        else {
            turn('+', cube[3]);
            for (int i = 0; i < 3; i++) {
                cube[0][0][i] = cube[5][i][2];
                cube[5][i][2= cube[1][0][i];
                cube[1][0][i] = cube[4][2 - i][0];
                cube[4][2 - i][0= temp[i];
            }
        }
    }
    else if (input[0== 'L') {    //왼쪽 면
        string temp = "";
        for (int i = 0; i < 3; i++) {
            temp += cube[0][i][0];
        }
 
        if (input[1== '-') {
            turn('-', cube[4]);
            for (int i = 0; i < 3; i++) {
                cube[0][i][0= cube[2][i][0];
                cube[2][i][0= cube[1][2 - i][2];
                cube[1][2 - i][2= cube[3][2 - i][2];
                cube[3][2 - i][2= temp[i];
            }
        }
        else {
            turn('+', cube[4]);
            for (int i = 0; i < 3; i++) {
                cube[0][i][0= cube[3][2 - i][2];
                cube[3][2 - i][2= cube[1][2 - i][2];
                cube[1][2 - i][2= cube[2][i][0];
                cube[2][i][0= temp[i];
            }
        }
    }
    else {    //오른쪽 면
        string temp = "";
        for (int i = 0; i < 3; i++) {
            temp += cube[0][i][2];
        }
 
        if (input[1== '-') {
            turn('-', cube[5]);
            for (int i = 0; i < 3; i++) {
                cube[0][2 - i][2= cube[3][i][0];
                cube[3][i][0= cube[1][i][0];
                cube[1][i][0= cube[2][2 - i][2];
                cube[2][2 - i][2= temp[2 - i];
            }
        }
        else {
            turn('+', cube[5]);
            for (int i = 0; i < 3; i++) {
                cube[0][2 - i][2= cube[2][2 - i][2];
                cube[2][2 - i][2= cube[1][i][0];
                cube[1][i][0= cube[3][i][0];
                cube[3][i][0= temp[2 - i];
            }
        }
    }
}
 
int main()
{
    int T;
    scanf("%d"&T);
 
    for (int t = 0; t < T; t++) {
        string cube[6][3= {    //큐브 초기화
            {"www""www""www"},
            {"yyy""yyy""yyy"},
            {"rrr",    "rrr""rrr"},
            {"ooo",    "ooo""ooo"},
            {"ggg",    "ggg""ggg"},
            {"bbb",    "bbb""bbb"}
        };
        int n;
        scanf("%d"&n);
 
        for (int i = 0; i < n; i++) {
            char input[5];
            scanf("%s", input);
            change(input, cube);
        }
 
        for (int i = 0; i < 3; i++) {
            cout << cube[0][i] << endl;
        }
    }
}
cs
반응형
반응형

https://www.acmicpc.net/problem/17140

 

17140번: 이차원 배열과 연산

첫째 줄에 r, c, k가 주어진다. (1 ≤ r, c, k ≤ 100) 둘째 줄부터 3개의 줄에 배열 A에 들어있는 수가 주어진다. 배열 A에 들어있는 수는 100보다 작거나 같은 자연수이다.

www.acmicpc.net

 

 

[ 문제풀이 ]

 

1. 행과 열의 크기를 각각 저장합니다.

 

2. 행의 개수가 열의 개수보다 더 적다면 C연산을 아니라면 R연산을 실행해줍니다.

 

3. 원하는 위치의 수가 k와 일치한다면 연산을 실행한 횟수를 출력해주고, 실행 횟수가 100을 넘으면 -1을 출력해줍니다.

 

2번 과정에서 각 연산을 진행할 때 행 혹은 열 별로 연산을 진행해줍니다. 배열에 있는 숫자들을 map에 저장해주고, 저장된 map을 바탕으로 priority_queue에 push를 해줍니다. 행 혹은 열을 0으로 초기화하고, priority_queue에서 하나씩 pop 해주면서 배열을 채워주면 구현할 수 있습니다.

 

[ 소스코드 ]

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
#include<iostream>
#include<cstring>
#include<unordered_map>
#include<queue>
 
using namespace std;
 
struct node {
    int num;
    int cnt;
};
 
struct cmp {    //pq정렬
    bool operator()(node right, node left) {
        if (left.cnt == right.cnt) return left.num < right.num;
        return left.cnt < right.cnt;
    }
};
 
int r, c, k;
int arr[101][101];
int y, x;
 
void calR()    //R연산
{
    int temp = x;
    x = 0;
    for (int i = 1; i <= y; i++) {
        priority_queue<node, vector<node>, cmp> pq;
        unordered_map<intint> m;
        for (int j = 1; j <= temp; j++) {
            if (arr[i][j] != 0) {    //0이 아니라면 map에 저장
                m[arr[i][j]]++;
            }
        }
        
        for (auto it = m.begin(); it != m.end(); it++) {
            pq.push({ it->first, it->second });    
            //map에 저장된 숫자들을 pq에 push
        }
        memset(arr[i], 0sizeof(arr[i]));    
        //해당 행 0으로 초기화
 
        int size = pq.size();
        size = min(size50);
        x = max(x, size * 2);
 
        for (int j = 1; j <= size * 2; j += 2) {
            int num = pq.top().num;    //행 채우기
            int cnt = pq.top().cnt;
            pq.pop();
            arr[i][j] = num;
            arr[i][j + 1= cnt;
        }
    }
}
 
void calC()    //C연산
{
    int temp = y;
    y = 0;
    for (int i = 1; i <= x; i++) {
        priority_queue<node, vector<node>, cmp> pq;
        unordered_map<intint> m;
        for (int j = 1; j <= temp; j++) {
            if (arr[j][i] != 0) {    //0이 아니라면 map에 저장
                m[arr[j][i]]++;
            }
        }
 
        for (auto it = m.begin(); it != m.end(); it++) {
            pq.push({ it->first, it->second });    
            //map에 저장된 숫자들을 pq에 push
        }
        
        for (int j = 1; j <= temp; j++) {
            arr[j][i] = 0;    //해당 열 0으로 초기화
        }
 
        int size = pq.size();
        size = min(size50);
        y = max(y, size * 2);
 
        for (int j = 1; j <= size * 2; j += 2) {
            int num = pq.top().num;    //열 채우기
            int cnt = pq.top().cnt;
            pq.pop();
            arr[j][i] = num;
            arr[j + 1][i] = cnt;
        }
    }
}
 
int main()
{
    scanf("%d %d %d"&r, &c, &k);
 
    for (int i = 1; i < 4; i++) {
        for (int j = 1; j < 4; j++) {
            scanf("%d"&arr[i][j]);
        }
    }
 
    y = x = 3;
 
    for (int i = 0; i <= 100; i++) {
        if (arr[r][c] == k) {
            printf("%d", i);
            return 0;
        }
 
        if (y >= x) {
            calR();
        }
        else {
            calC();
        }
    }
 
    printf("%d"-1);
}
cs

 

 

 

반응형
반응형

https://www.acmicpc.net/problem/16235

 

16235번: 나무 재테크

부동산 투자로 억대의 돈을 번 상도는 최근 N×N 크기의 땅을 구매했다. 상도는 손쉬운 땅 관리를 위해 땅을 1×1 크기의 칸으로 나누어 놓았다. 각각의 칸은 (r, c)로 나타내며, r은 가장 위에서부터

www.acmicpc.net

 

 

[ 문제풀이 ]

 

1. 같은 나이의 나무가 많기 때문에 겹치는 나무를 쉽게 관리하기 위해 map 자료 구조를 써서 나무의 개수를 저장합니다.

 

2. 봄과 여름은 동시에 진행 가능하고, 가을과 겨울도 동시에 진행 가능하기 때문에 봄과 여름을 먼저 진행하고, 가을과 겨울을 진행합니다.

 

3. 살아있는 나무의 개수를 세어 ans에 더해줍니다.

 

4. ans를 출력합니다.

 

[ 소스코드 ]

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
#include<iostream>
#include<map>
 
using namespace std;
 
struct tree {
    long long energy = 5;
    int cnt;
    map<intlong long> alive;
    map<intlong long> dead;
};
 
int N, M, K;
int A[11][11];
tree arr[11][11];
int dy[8= { -1,-1,0,1,1,1,0,-1 };
int dx[8= { 0,1,1,1,0,-1,-1,-1 };
 
void breeding(int y, int x)    //가을 번식
{
    for (int i = 0; i < 8; i++) {
        int yy = y + dy[i];
        int xx = x + dx[i];
        if (yy > 0 && yy <= N && xx > 0 && xx <= N) {
            arr[yy][xx].alive[1+= arr[y][x].cnt;
        }
    }
    arr[y][x].cnt = 0;
}
 
void seasons()    //계절 변화에 따라 map배열 갱신
{
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= N; j++) {
            if (arr[i][j].alive.empty()) continue;
            map<intlong long> temp = arr[i][j].alive;
            arr[i][j].alive.clear();
            for (auto it = temp.begin(); it != temp.end(); it++) {    //봄
                int ret = (it->first) * (it->second);
                if (ret <= arr[i][j].energy) {
                    arr[i][j].energy -= ret;
                    arr[i][j].alive[(it->first) + 1+= it->second;
                    if (((it->first) + 1) % 5 == 0) {
                        arr[i][j].cnt += it->second;
                    }
                }
                else {
                    int cnt = arr[i][j].energy / (it->first);
                    arr[i][j].energy -= cnt * (it->first);
                    if (cnt > 0) {
                        arr[i][j].alive[(it->first) + 1+= cnt;
                    }
                    if (((it->first) + 1) % 5 == 0) {
                        arr[i][j].cnt += cnt;
                    }
                    arr[i][j].dead[it->first] = (it->second) - cnt;
                }
            }
 
            temp = arr[i][j].dead;    //여름
            for (auto it = temp.begin(); it != temp.end(); it++) {
                arr[i][j].energy += (it->first/2* (it->second);
            }
            arr[i][j].dead.clear();
        }
    }
 
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= N; j++) {
            if (arr[i][j].cnt) {
                breeding(i, j);    //가을
            }
            arr[i][j].energy += A[i][j];    //겨울
        }
    }
}
 
int main()
{
    scanf("%d %d %d"&N, &M, &K);
 
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= N; j++) {
            scanf("%d"&A[i][j]);
        }
    }
 
    for (int i = 0; i < M; i++) {
        int x, y, z;
        scanf("%d %d %d"&x, &y, &z);
        arr[x][y].alive[z]++;
    }
 
    for (int i = 0; i < K; i++) {
        seasons();
    }
 
    int ans = 0;
 
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= N; j++) {
            for (auto it = arr[i][j].alive.begin(); it != arr[i][j].alive.end(); it++) {
                ans += it->second;
            }
        }
    }
 
    printf("%d", ans);
}
cs
반응형
반응형

https://www.acmicpc.net/problem/15685

 

15685번: 드래곤 커브

첫째 줄에 드래곤 커브의 개수 N(1 ≤ N ≤ 20)이 주어진다. 둘째 줄부터 N개의 줄에는 드래곤 커브의 정보가 주어진다. 드래곤 커브의 정보는 네 정수 x, y, d, g로 이루어져 있다. x와 y는 드래곤 커

www.acmicpc.net

 

 

[ 문제풀이 ]

 

1. 주어지는 입력에 따라 드래곤 커브를 그립니다.

 

2. 그려진 드래곤 커브를 바탕으로 꼭짓점이 모두 드래곤 커브에 속한다면 ans에 1을 더해줍니다.

 

3. ans를 출력합니다.

 

위의 1번에서 드래곤 커브를 그리는 방식을 찾는 데 시간이 조금 걸렸습니다. x좌표의 경우 90도 변경될 때 y좌표 방향으로 상대 좌표의 값이 변경되지 않습니다. 하지만 y좌표의 경우 90도 회전할 때 x좌표 방향으로 상대 좌표의 값에 -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
#include<iostream>
#include<vector>
 
using namespace std;
 
struct pos {
    int y;
    int x;
    bool dot;
};
 
int N;
int arr[101][101];
int dy[4= { 0,-1,0,1 };
int dx[4= { 1,0,-1,0 };
 
vector<pos> gen(vector<pos> vect)    //드래곤 커브 그리기
{
    int idx,y,x;
    int size = vect.size();
    for (int i = 0; i < size;i++) {    //드래곤 커브의 끝 점
        if (vect[i].dot == 1) {
            y = vect[i].y;
            x = vect[i].x;
            vect[i].dot = 0;
            idx = i;
            break;
        }
    }
 
    for (int i = 0; i < size; i++) {
        if (idx != i) {
            int yy = vect[i].y - y;    //끝 점 기준으로 상대 위치 저장
            int xx = vect[i].x - x;
            int tempX = -yy;
            int tempY = xx;
            xx = x + tempX;        //이동한 점의 좌표
            yy = y + tempY;
            if (i == 0) {    //첫 점은 다음 드래곤 커브의 끝 점
                vect.push_back({ yy,xx,1 });
            }
            else {
                vect.push_back({ yy,xx });
            }
            arr[yy][xx] = 1;
        }
    }
 
    return vect;
}
 
int main()
{
    scanf("%d"&N);
 
    for (int i = 0; i < N; i++) {
        int x, y, d, g;
        scanf("%d %d %d %d"&x, &y, &d, &g);
        int yy = y + dy[d];
        int xx = x + dx[d];
        vector<pos> vect;
        vect.push_back({ y,x });
        vect.push_back({ yy,xx,1 });
        arr[y][x] = 1;
        arr[yy][xx] = 1;
 
        for (int j = 0; j < g; j++) {
            vect = gen(vect);
        }
    }
 
    int ans = 0;
 
    for (int i = 0; i < 100; i++) {    //꼭짓점이 모두 드래곤 커브인 정사각형 개수 구하기
        for (int j = 0; j < 100; j++) {
            if (arr[i][j] == 1 && arr[i + 1][j] == 1 && arr[i][j + 1== 1 && arr[i + 1][j + 1== 1) {
                ans++;
            }
        }
    }
 
    printf("%d", ans);
}
cs
반응형
반응형

https://www.acmicpc.net/problem/15683

 

15683번: 감시

스타트링크의 사무실은 1×1크기의 정사각형으로 나누어져 있는 N×M 크기의 직사각형으로 나타낼 수 있다. 사무실에는 총 K개의 CCTV가 설치되어져 있는데, CCTV는 5가지 종류가 있다. 각 CCTV가 감

www.acmicpc.net

 

 

[ 문제풀이 ]

 

1. cctv가 있는 위치를 vector에 저장하고 총 개수를 limit변수에 저장합니다.

 

2. 재귀 호출을 통해 모든 cctv의 방향을 설정하고, #으로 바꿉니다.

 

3. 모든 cctv의 방향을 설정했다면 사각지대의 개수를 세어 ans와 비교해 저장합니다.

 

4. 답을 출력합니다.

 

[ 소스코드 ]

 

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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
#include<iostream>
#include<vector>
 
using namespace std;
 
int N, M;
int arr[8][8];
int limit;
vector<pair<intint>> pos;
int ans = 987654321;
 
void cctv(int y, int x, int dir)    //cctv가 보는 방향을 #으로 초기화
{
    if (dir == 0) {
        for (int i = 1; i < M; i++) {
            if (x + i >= M) break;
            int temp = arr[y][x + i];
            if (temp == 6) {
                break;
            }
            else if (temp > 0 && temp < 6) {
                continue;
            }
            else {
                arr[y][x + i] = '#';
            }
 
        }
    }
    else if (dir == 1) {
        for (int i = 1; i < N; i++) {
            if (y + i >= N) break;
            int temp = arr[y + i][x];
            if (temp == 6) {
                break;
            }
            else if (temp > 0 && temp < 6) {
                continue;
            }
            else {
                arr[y + i][x] = '#';
            }
 
        }
    }
    else if (dir == 2) {
        for (int i = 1; i < M; i++) {
            if (x - i < 0break;
            int temp = arr[y][x - i];
            if (temp == 6) {
                break;
            }
            else if (temp > 0 && temp < 6) {
                continue;
            }
            else {
                arr[y][x - i] = '#';
            }
 
        }
    }
    else {
        for (int i = 1; i < N; i++) {
            if (y - i < 0break;
            int temp = arr[y - i][x];
            if (temp == 6) {
                break;
            }
            else if (temp > 0 && temp < 6) {
                continue;
            }
            else {
                arr[y - i][x] = '#';
            }
 
        }
    }
}
 
int blind()    //사각지대 개수 세기
{
    int ret = 0;
 
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (arr[i][j] == 0) {
                ret++;
            }
        }
    }
 
    return ret;
}
 
void dfs(int level)
{
    if (level == limit) {
        int cnt = blind();
        ans = min(ans, cnt);
        return;
    }
 
    int temp[8][8= { 0 };
    for (int i = 0; i < N; i++) {    //백트래킹을 위한 저장
        for (int j = 0; j < M; j++) {
            temp[i][j] = arr[i][j];
        }
    }
 
    int y = pos[level].first;
    int x = pos[level].second;
    int num = arr[y][x];
 
    if (num == 1) {    //1번 cctv
        for (int i = 0; i < 4; i++) {
            cctv(y, x, i);
            dfs(level + 1);
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < M; j++) {
                    arr[i][j] = temp[i][j];
                }
            }
        }
    }
    else if (num == 2) {    //2번 cctv
        for (int i = 0; i < 2; i++) {
            if (i == 0) {
                cctv(y, x, 0);
                cctv(y, x, 2);
            }
            else {
                cctv(y, x, 1);
                cctv(y, x, 3);
            }
            dfs(level + 1);
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < M; j++) {
                    arr[i][j] = temp[i][j];
                }
            }
        }
    }
    else if (num == 3) {    //3번 cctv
        for (int i = 0; i < 4; i++) {
            int dir1 = 0 + i;
            int dir2 = 1 + i;
            if (dir2 > 3) {
                dir2 -= 4;
            }
            cctv(y, x, dir1);
            cctv(y, x, dir2);
            dfs(level + 1);
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < M; j++) {
                    arr[i][j] = temp[i][j];
                }
            }
        }
    }
    else if (num == 4) {    //4번 cctv
        for (int i = 0; i < 4; i++) {
            int dir1 = 0 + i;
            int dir2 = 1 + i;
            int dir3 = 2 + i;
            if (dir2 > 3) {
                dir2 -= 4;
            }
            if (dir3 > 3) {
                dir3 -= 4;
            }
            cctv(y, x, dir1);
            cctv(y, x, dir2);
            cctv(y, x, dir3);
            dfs(level + 1);
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < M; j++) {
                    arr[i][j] = temp[i][j];
                }
            }
        }
    }
    else {    //5번 cctv
        for (int i = 0; i < 4; i++) {
            cctv(y, x, i);
        }
        dfs(level + 1);
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                arr[i][j] = temp[i][j];
            }
        }
    }
}
 
int main()
{
    scanf("%d %d"&N, &M);
 
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            scanf("%d"&arr[i][j]);
            if (arr[i][j] > 0 && arr[i][j] < 6) {
                pos.push_back({ i, j });
                limit++;
            }
        }
    }
 
    dfs(0);
 
    printf("%d", ans);
}
cs
반응형
반응형

https://www.acmicpc.net/problem/15684

 

15684번: 사다리 조작

사다리 게임은 N개의 세로선과 M개의 가로선으로 이루어져 있다. 인접한 세로선 사이에는 가로선을 놓을 수 있는데, 각각의 세로선마다 가로선을 놓을 수 있는 위치의 개수는 H이고, 모든 세로선

www.acmicpc.net

 

 

[ 문제풀이 ]

 

1. 초기 사다리의 모양을 입력받습니다.

 

2. 재귀 호출을 통해서 현재 위치에 사다리가 없고, 양 옆에도 사다리가 없다면 사다리를 놓고 cnt를 1 더해줍니다.

 

3. 현재 놓은 사다리 개수가 놓아야 하는 사다리 개수와 같다면 check 함수를 통해서 유효한 위치인지 확인합니다.

 

4. 위 순서로 놓아야 하는 사다리 개수를 0 ~ 3까지 늘려가며 반복하고, 중간에 만족하는 경우가 나오면 해당 사다리 개수를 출력하고, 그렇지 않다면 -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
#include<iostream>
 
using namespace std;
 
int N, M, H;
int arr[30][11];
int cnt;
bool cur;
 
bool check()    //i번 세로선의 결과가 i번이 아니면 false return
{
    for (int i = 0; i < N; i++) {
        int temp = i;
        for (int j = 0; j < H; j++) {
            if (arr[j][temp] == 1) {
                temp--;
            }
            else if (arr[j][temp + 1== 1) {
                temp++;
            }
        }
        if (temp != i) return false;
    }
 
    return true;
}
 
void dfs(int limit, int num)
{
    if (cur == truereturn;
    if (cnt == limit) {    //줄의 개수가 limit이라면 check
        if (check()) {
            cur = true;
        }
        return;
    }
 
    for (int i = num; i < (N - 1* H; i++) {
        int y = i / (N - 1);
        int x = i % (N - 1);
        x += 1;
        if (arr[y][x] == 0 && arr[y][x+1!= 1 && arr[y][x-1!= 1) {    //사다리를 놓을 수 있다면
            arr[y][x] = 1;    //사다리 위치
            cnt++;
            dfs(limit, i+1);
            cnt--;
            arr[y][x] = 0;
        }
    }
}
 
int main()
{
    scanf("%d %d %d"&N, &M, &H);
 
    for (int i = 0; i < M; i++) {
        int a, b;
        scanf("%d %d"&a, &b);
 
        arr[a-1][b] = 1;
    }
 
    for (int i = 0; i < 4; i++) {    //가로선의 개수 0 ~ 3
        cur = false;
        dfs(i, 0);
        if (cur == true) {
            printf("%d", i);
            return 0;
        }
    }
 
    printf("%d"-1);
}
cs
반응형
반응형

https://www.acmicpc.net/problem/14890

 

14890번: 경사로

첫째 줄에 N (2 ≤ N ≤ 100)과 L (1 ≤ L ≤ N)이 주어진다. 둘째 줄부터 N개의 줄에 지도가 주어진다. 각 칸의 높이는 10보다 작거나 같은 자연수이다.

www.acmicpc.net

 

 

[ 문제풀이 ]

 

1. 길의 왼쪽부터 탐색하면서 경사로를 놓을 수 있는지 없는지 체크합니다.

 

2. 길의 오른쪽부터 탐색하면서 경사로를 놓을 수 있는지 없는지 체크합니다.

 

3. 위의 1, 2의 과정 중 하나라도 만족하지 않는다면 false를 반환하고, 둘 다 만족하면 true를 반환합니다.

 

4. true를 반환한 도로의 개수를 ans에 저장해 출력합니다.

 

[ 소스코드 ]

 

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
#include<iostream>
 
using namespace std;
 
int N, L;
int arr1[100][100];
int arr2[100][100];
 
bool check(int num, int arr[][100])    //길의 통과 여부 확인
{
    int visited[100= { 0 };
    for (int i = 0; i < N - 1; i++) {
        if (arr[num][i] - arr[num][i + 1== 1) {
            if (i >= N - L) return false;
            int temp = arr[num][i + 1];
            for (int j = 0; j < L; j++) {
                if (visited[i + 1 + j] == 1 || temp != arr[num][i + 1 + j]) return false;
                temp = arr[num][i + 1 + j];
                visited[i + 1 + j] = 1;
            }
        }
        else if (arr[num][i] - arr[num][i + 1> 1) {
            return false;
        }
    }
 
    for (int i = N - 1; i >= 1; i--) {
        if (arr[num][i] - arr[num][i - 1== 1) {
            if (i < L) return false;
            int temp = arr[num][i - 1];
            for (int j = 0; j < L; j++) {
                if (visited[i - 1 - j] == 1 || temp != arr[num][i - 1 - j]) return false;
                temp = arr[num][i - 1 - j];
                visited[i - 1 - j] = 1;
            }
        }
        else if (arr[num][i] - arr[num][i - 1> 1) {
            return false;
        }
    }
 
    return true;
}
 
int main()
{
    scanf("%d %d"&N, &L);
 
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            int num;
            scanf("%d"&num);
            arr1[i][j] = num;
            arr2[j][i] = num;
 
        }
    }
 
    int ans = 0;
 
    for (int i = 0; i < N; i++) {
        if (check(i, arr1)) ans++;
        if (check(i, arr2)) ans++;
    }
 
    printf("%d", ans);
}
cs
반응형
반응형

https://www.acmicpc.net/problem/14891

 

14891번: 톱니바퀴

첫째 줄에 1번 톱니바퀴의 상태, 둘째 줄에 2번 톱니바퀴의 상태, 셋째 줄에 3번 톱니바퀴의 상태, 넷째 줄에 4번 톱니바퀴의 상태가 주어진다. 상태는 8개의 정수로 이루어져 있고, 12시방향부터

www.acmicpc.net

 

 

[ 문제풀이 ]

 

1. 왼쪽과 오른쪽에 있는 톱니바퀴의 극성이 다른지 체크 후 다르다면 재귀 함수를 이용하여 해당 톱니바퀴로 이동하고, 방문 여부를 저장해 한번 움직인 톱니바퀴는 움직이지 않도록 합니다.

 

2. 재귀함수가 끝나면 해당 톱니바퀴를 해당 방향으로 움직여줍니다.

 

3. 마지막에 12시 방향이 S극이라면 해당 톱니바퀴마다 점수를 더해 출력해줍니다.

 

[ 소스코드 ]

 

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
#include<iostream>
#include<string>
#include<cmath>
 
using namespace std;
 
string arr[5];
int K;
 
void move(int num, int dir)    //톱니바퀴 이동
{
    if (dir == 1) {
        char temp = arr[num][7];
        for (int i = 7; i > 0; i--) {
            arr[num][i] = arr[num][i - 1];
        }
        arr[num][0= temp;
    }
    else {
        char temp = arr[num][0];
        for (int i = 0; i < 7; i++) {
            arr[num][i] = arr[num][i + 1];
        }
        arr[num][7= temp;
    }
}
 
void check(int num, int dir, int visited[5])    //움직일지 말지 정하기
{
    visited[num] = 1;
    if (num == 1) {
        if (arr[num][2!= arr[num + 1][6]) {
            if (visited[2!= 1) {
                check(2, dir * -1, visited);
            }
        }
    }
    else if (num == 2) {
        if (arr[num][2!= arr[num + 1][6]) {
            if (visited[3!= 1) {
                check(3, dir * -1, visited);
            }
        }
        if (arr[num][6!= arr[num - 1][2]) {
            if (visited[1!= 1) {
                check(1, dir * -1, visited);
            }
        }
    }
    else if (num == 3) {
        if (arr[num][2!= arr[num + 1][6]) {
            if (visited[4!= 1) {
                check(4, dir * -1, visited);
            }
        }
        if (arr[num][6!= arr[num - 1][2]) {
            if (visited[2!= 1) {
                check(2, dir * -1, visited);
            }
        }
    }
    else {
        if (arr[num][6!= arr[num - 1][2]) {
            if (visited[3!= 1) {
                check(3, dir * -1, visited);
            }
        }
    }
 
    move(num, dir);
}
 
int main()
{
    for (int i = 1; i <= 4; i++) {
        cin >> arr[i];
    }
    scanf("%d"&K);
 
    for (int i = 0; i < K; i++) {
        int num, dir;
        int visited[5= { 0 };
 
        scanf("%d %d"&num, &dir);
 
        check(num, dir, visited);
    }
 
    int ans = 0;
 
    for (int i = 1; i <= 4; i++) {
        if (arr[i][0== '1') {
            ans += pow(2, i - 1);
        }
    }
 
    printf("%d", ans);
}
cs
반응형
반응형

https://www.acmicpc.net/problem/20055

 

20055번: 컨베이어 벨트 위의 로봇

길이가 N인 컨베이어 벨트가 있고, 길이가 2N인 벨트가 이 컨베이어 벨트를 위아래로 감싸며 돌고 있다. 벨트는 길이 1 간격으로 2N개의 칸으로 나뉘어져 있으며, 각 칸에는 아래 그림과 같이 1부

www.acmicpc.net

 

 

[ 문제풀이 ]

 

1. 컨베이어 벨트를 로봇과 함께 한 칸씩 옮깁니다.

 

2. 로봇이 움직일 수 있는 상황이라면 벨트가 움직이는 방향으로 한 칸씩 더 움직여줍니다.

 

3. 맨 처음 칸의 내구도가 0이 아니라면 로봇을 하나 올립니다.

 

4. 내구도가 0인 칸의 개수가 K개 이상이라면 멈추고, 아니라면 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
#include<iostream>
 
using namespace std;
 
int N, K;
int arr[201];
int robot[101];
 
int main()
{
    scanf("%d %d"&N, &K);
 
    for (int i = 1; i <= 2*N; i++) {
        scanf("%d"&arr[i]);
    }
    
    int ans = 0;
 
    while (1) {
        ans++;
        int temp = arr[2 * N];
 
        for (int i = 2 * N; i > 0; i--) {    //벨트 옮기기
            arr[i] = arr[i - 1];
        }
        for (int i = N; i > 0; i--) {    //벨트와 같이 로봇 옮기기
            robot[i] = robot[i - 1];
        }
        robot[1= 0;
        arr[1= temp;
 
        robot[N] = 0;
        for (int i = N - 1; i > 0; i--) {    //로봇 스스로 움직이기
            if (robot[i] == 1) {
                if (arr[i + 1> 0 && robot[i + 1!= 1) {
                    robot[i + 1= 1;
                    robot[i] = 0;
                    arr[i + 1]--;
                }
            }
        }
 
        if (arr[1!= 0) {    //올리는 위치에 로봇 올리기
            arr[1]--;
            robot[1= 1;
        }
 
        int cnt = 0;
        for (int i = 1; i <= 2 * N; i++) {    //내구도 0인 칸 개수
            if (arr[i] == 0) cnt++;
        }
 
        if (cnt >= K) {
            printf("%d", ans);
            return 0;
        }
    }
}
cs
반응형

+ Recent posts