반응형

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

 

8981번: 입력숫자

첫 줄에는 정수 N이 제시되어 있고, 그 다음 줄에는 N개의 양의 정수가 빈칸을 사이에 두고 기록되어 있어야 한다. 만일 입력을 생성하는 mystery.c의 입력파일 X가 없는 경우에는 음수인 -1 을 첫 줄

www.acmicpc.net

 

 

[ 문제풀이 ]

 

1. Y배열을 보고 X배열을 역으로 구해내야 하는 문제입니다.

 

2. 값과 인덱스를 더한 뒤 모듈러 연산을 통해 인덱스를 갱신하고, 해당 인덱스에 값이 없다면 값을 넣고, 값이 있다면 인덱스에 +1을 하여 위 과정을 반복합니다.

 

3. X배열을 출력합니다.

 

[ 소스코드 ]

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
#include <iostream>
 
using namespace std;
 
int NUM[101];
int ans[101];
 
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
 
    int i, token, N;
    int count = 1, from = 0, value;
    
    cin >> N;
    for (i = 0; i < N; i++) {
        cin >> token;
        NUM[i] = token;
    }
 
    ans[0= NUM[0];
 
    cout << N << '\n';
 
    int cur = 0;
 
    while (count < N) {
        value = ans[cur];
        cur = (cur + value) % N;
        while (ans[cur] != 0) cur = (cur + 1) % N;
        ans[cur] = NUM[count];
        count++;
    }
 
    for (int i = 0; i < N; i++) {
        cout << ans[i] << ' ';
    }
}
cs
반응형
반응형

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

 

2669번: 직사각형 네개의 합집합의 면적 구하기

평면에 네 개의 직사각형이 놓여 있는데 그 밑변은 모두 가로축에 평행하다. 이 네 개의 직사각형들은 서로 떨어져 있을 수도 있고, 겹쳐 있을 수도 있고, 하나가 다른 하나를 포함할 수도 있으

www.acmicpc.net

 

 

[ 문제풀이 ]

 

1. arr배열을 만들어 입력받은 좌표들을 for문을 이용해 탐색하면서 값을 1로 바꾸어주고, 그 개수를 세어줍니다.

 

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
#include<iostream>
 
using namespace std;
 
int arr[101][101];
int ans;
 
int main()
{
    for (int i = 0; i < 4; i++) {
        int x1, y1, x2, y2;
        scanf("%d %d %d %d"&x1, &y1, &x2, &y2);
 
        for (int j = x1; j < x2; j++) {
            for (int k = y1; k < y2; k++) {
                if (arr[j][k] == 0) {
                    arr[j][k] = 1;
                    ans++;
                }
            }
        }
    }
 
    printf("%d", ans);
}
cs
반응형

'백준' 카테고리의 다른 글

[ 백준 ] 2830번 - 행성 X3 (C++)  (0) 2023.06.20
[ 백준 ] 5022번 - 연결 (C++)  (1) 2023.06.19
[ 백준 ] 2164번 - 카드2 (C++)  (0) 2023.06.17
[ 백준 ] 14497번 - 주난의 난(難) (C++)  (0) 2023.06.16
[ 백준 ] 10464번 - XOR (C++)  (0) 2023.06.15
반응형

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

 

7490번: 0 만들기

각 테스트 케이스에 대해 ASCII 순서에 따라 결과가 0이 되는 모든 수식을 출력한다. 각 테스트 케이스의 결과는 한 줄을 띄워 구분한다.

www.acmicpc.net

 

 

[ 문제풀이 ]

 

1. 백트래킹을 이용해 실시간으로 계산값들을 저장하고, 각 인덱스에 저장되어 있는 부호가 무엇인지 저장합니다.

 

2. 만약 계산값이 0이라면 vector<stirng> ans에 숫자와 부호를 push합니다.

 

3. 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
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
 
using namespace std;
 
int N;
int ret = 0;
char box[10];
vector<string> ans;
 
void dfs(int level, int num, int idx)
{
    if (level == N + 1) {
        if (num != 0) {
            if (box[idx] == '-') {
                ret -= num;
            }
            else {
                ret += num;
            }
        }
        if (ret == 0) {
            string temp;
            for (int i = 1; i <= N; i++) {
                temp += '0' + i;
                temp += box[i];
            }
            ans.push_back(temp);
        }
        if (num != 0) {
            if (box[idx] == '-') {
                ret += num;
            }
            else {
                ret -= num;
            }
        }
        return;
    }
 
    num = num * 10 + level;
 
    if (N != level) {
        if (box[idx] == '-') {
            ret -= num;
            box[level] = '+';
            dfs(level + 10, level);
            box[level] = '-';
            dfs(level + 10, level);
            ret += num;
            box[level] = 0;
        }
        else {
            ret += num;
            box[level] = '+';
            dfs(level + 10, level);
            box[level] = '-';
            dfs(level + 10, level);
            ret -= num;
            box[level] = 0;
        }
    }
 
    box[level] = ' ';
    dfs(level + 1, num, idx);
    box[level] = 0;
 
    return;
}
 
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
 
    int T;
    cin >> T;
 
    for (int t = 0; t < T; t++) {
        ans.clear();
        cin >> N;
 
        dfs(1,0,0);
 
        sort(ans.begin(), ans.end());
 
        for (auto& next : ans) {
            cout << next << '\n';
        }
 
        cout << '\n';
    }
}
cs

 

반응형
반응형

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

 

10836번: 여왕벌

입력의 첫 줄에는 격자칸의 가로와 세로 크기 M(2 ≤ M ≤ 700)과 날짜 수 N(1 ≤ N ≤ 1,000,000)이 자연수로 주어진다. 첫날 아침의 애벌레 크기는 모두 1이므로 입력에 주어지지 않는다. 다음 N개의

www.acmicpc.net

 

 

[ 문제풀이 ]

 

1. 1열을 제외한 나머지 열은 1행의 값과 동일하기 때문에 맨 왼쪽 1열과 맨 위쪽 1행의 값만 갱신해 주면 됩니다.

 

2. arr[1400] 배열을 만들어서 입력되는 수열대로 값을 증가시켜 줍니다.

 

3. 0 ~ M - 1 인덱스는 맨 왼쪽 1 열이므로 M - 1부터 0까지 for문을 돌면서 1열을 출력하고, 2열부터는 M ~ 2 * M - 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
#include<iostream>
 
using namespace std;
 
int M, N;
int arr[1400];
 
int main()
{
    scanf("%d %d", &M, &N);
 
    for (int i = 0; i < N; i++) {
        int n[3];
        int idx = 1;
        scanf("%d %d %d", &n[0], &n[1], &n[2]);
 
        for (int i = n[0]; i < n[0]+n[1]; i++) {
            arr[i] += 1;
        }
 
        for (int i = n[0] + n[1]; i < 2 * M - 1; i++) {
            arr[i] += 2;
        }
    }
 
    for (int i = M - 1; i >= 0; i--) {
        printf("%d ", arr[i] + 1);
        for (int j = M; j < 2 * M - 1; j++) {
            printf("%d ", arr[j] + 1);
        }
        printf("\n");
    }
}
cs
반응형
반응형

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

 

18405번: 경쟁적 전염

첫째 줄에 자연수 N, K가 공백을 기준으로 구분되어 주어진다. (1 ≤ N ≤ 200, 1 ≤ K ≤ 1,000) 둘째 줄부터 N개의 줄에 걸쳐서 시험관의 정보가 주어진다. 각 행은 N개의 원소로 구성되며, 해당 위치

www.acmicpc.net

 

 

[ 문제풀이 ]

 

1. priority_queue를 만들어서 바이러스의 번호의 오름차순으로 좌표를 넣습니다.

 

2. bfs를 통해 시험관을 채워주고, 만약 입력받은 좌표에 바이러스가 생기면 그 바이러스 번호를 출력하고 프로그램을 종료합니다.

 

3. 시간이 다 지날 때까지 바이러스가 존재하지 않는다면 0을 출력합니다.

 

[ 소스코드 ]

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
#include<iostream>
#include<queue>
 
using namespace std;
 
int N, K;
int arr[201][201];
int dx[4= { -1,1,0,0 };
int dy[4= { 0,0,-1,1 };
 
struct node {
    int x;
    int y;
    int cnt;
};
 
struct cmp {
    bool operator()(node right, node left) {
        if (left.cnt == right.cnt) return arr[left.x][left.y] < arr[right.x][right.y];
        return left.cnt < right.cnt;
    }
};
 
int main()
{
    scanf("%d %d"&N, &K);
    priority_queue<node, vector<node>, cmp> pq;
 
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= N; j++) {
            scanf("%d"&arr[i][j]);
            if (arr[i][j] != 0) {
                pq.push({ i,j,0 });
            }
        }
    }
 
    int S, X, Y;
    scanf("%d %d %d"&S, &X, &Y);
    
    while(!pq.empty()) {
        const int x = pq.top().x;
        const int y = pq.top().y;
        const int cnt = pq.top().cnt;
        pq.pop();
 
        if (arr[X][Y] != 0) {
            printf("%d", arr[X][Y]);
            return 0;
        }
 
        if (cnt == S) continue;
 
        for (int i = 0; i < 4; i++) {
            const int xx = x + dx[i];
            const int yy = y + dy[i];
 
            if (xx > 0 && xx <= N && yy > 0 && yy <= N) {
                if (arr[xx][yy] == 0) {
                    arr[xx][yy] = arr[x][y];
                    pq.push({ xx,yy,cnt + 1 });
                }
            }
        }
    }
 
    printf("%d", arr[X][Y]);
}
cs
반응형
반응형

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

 

5529번: 저택

첫째 줄에 집의 크기 M, N과 스위치가 있는 방의 수 K가 주어진다. 둘째 줄부터 K개 줄에는 스위치가 있는 방의 위치 (xi, yi)가 주어진다. (2 ≤ M,N ≤ 100,000, 1 ≤ K ≤ 200,000)

www.acmicpc.net

 

 

[ 문제풀이 ]

 

1. 각각의 x, y 좌표에 있는 버튼들을 sero, garo 배열에 저장합니다.

 

2. 각각의 sero, garo 배열을 오름차순으로 정렬 후 인접해 있는 점끼리 간선으로 연결합니다.

 

3. 버튼을 누르면 1분이 경과하므로 버튼끼리 거리 1인 간선으로 연결해 줍니다.

 

4. 출발점을 1, 0으로 두고 노드를 추가합니다. 그리고 도착점인 M, N도 노드에 추가합니다.

 

5. 데이크스트라를 이용하여 가장 빨리 도착할 수 있는 시간을 출력합니다.

 

[ 소스코드 ]

 

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
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<fstream>
#define INF 0x3f3f3f3f3f3f3f3f
 
using namespace std;
 
int N, M, K;
vector<pair<intint>> sero[100002];    //특정 x좌표의 버튼을 저장할 배열
vector<pair<intint>> garo[100002];    //특정 y좌표의 버튼을 저장할 배열
vector<pair<intlong long>> graph[400015];        //버튼간 연결되는 간선 저장
long long dist[400015];        //각 버튼까지 도착했을 때까지 걸린 시간 저장
 
int main()
{
    //freopen("input.txt", "r", stdin);
 
    scanf("%d %d %d"&M, &N, &K);
 
    bool E = true;
 
    for (int i = 0; i <= (K+ 1* 2 + 1; i++) {
        dist[i] = INF;
    }
 
    for (int i = 1; i <= K; i++) {
        int m, n;
        scanf("%d %d"&m, &n);
 
        sero[m].emplace_back(n, i);
        garo[n].emplace_back(m, i);
    }
    sero[1].emplace_back(00);        //1,0 좌표에서 출발
 
    sero[M].emplace_back(N, K + 1);    //도착지
    garo[N].emplace_back(M, K + 1);
 
    for (int i = 1; i <= K; i++) {    //방향 변경시 버튼을 누르면 1분 경과
        graph[i * 2].emplace_back(i * 2 + 11);
        graph[i * 2 + 1].emplace_back(i * 21);
    }
 
    for (int i = 1; i <= N; i++) {
        sort(garo[i].begin(), garo[i].end());
    }
    for (int i = 1; i <= M; i++) {
        sort(sero[i].begin(), sero[i].end());
    }
 
    for (int i = 0; i <= N; i++) {
        for (int j = 0; j < (int)garo[i].size() - 1; j++) {
            const int dist = garo[i][j + 1].first - garo[i][j].first;
            const int u = garo[i][j + 1].second;
            const int v = garo[i][j].second;
            graph[u * 2].emplace_back(v * 2, dist);        //가로 방향 간선 연결
            graph[v * 2].emplace_back(u * 2, dist);
        }
    }
 
    for (int i = 0; i <= M; i++) {
        for (int j = 0; j < (int)sero[i].size() - 1; j++) {
            const int dist = sero[i][j + 1].first - sero[i][j].first;
            const int u = sero[i][j + 1].second;
            const int v = sero[i][j].second;
            graph[u * 2 + 1].emplace_back(v * 2 + 1, dist);    //세로 방향 간선 연결
            graph[v * 2 + 1].emplace_back(u * 2 + 1, dist);
        }
    }
 
    priority_queue<pair<long long,int>vector<pair<long longint>>, greater<pair<long longint>>> pq;
 
    pq.push({-1,1});
    while (!pq.empty()) {
        const long long curDist = pq.top().first;
        const int curId = pq.top().second;
        pq.pop();
 
        if (dist[curId] < curDist) continue;
 
        for (auto &next : graph[curId]) {
            const int nextId = next.first;
            const long long nextDist = next.second;
 
            if (dist[nextId] > curDist + nextDist) {
                dist[nextId] = curDist + nextDist;
                pq.push({ dist[nextId], nextId });
            }
        }
    }
 
    if (dist[(K + 1)*2== INF && dist[(K+1)*2+1== INF) {
        printf("%d"-1);
    }
    else {
        printf("%lld", min(dist[(K + 1* 2], dist[(K + 1* 2 + 1]));
    }
}
cs
반응형
반응형

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

 

7682번: 틱택토

틱택토 게임은 두 명의 사람이 번갈아가며 말을 놓는 게임이다. 게임판은 3×3 격자판이며, 처음에는 비어 있다. 두 사람은 각각 X 또는 O 말을 번갈아가며 놓는데, 반드시 첫 번째 사람이 X를 놓고

www.acmicpc.net

 

 

[ 문제풀이 ]

 

1. 백트래킹을 이용하여 가능한 모든 경우의 수를 map에 저장합니다.

 

2. 결과를 입력받고 map에 있는지 체크한 후 있다면 valid, 없다면 invalid를 출력해줍니다.

 

[ 소스코드 ]

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>
#include<string>
#include<cstring>
#include<unordered_map>
 
using namespace std;
 
char tik[10];
char temp[10= ".........";
unordered_map<stringbool> m;
 
void dfs(int level) 
{
    if (level == 9) {
        m[temp] = true;    //승부가 나지 않았을 때
        return;
    }
 
    for (int i = 0; i < 3; i++) {
        if (temp[i * 3== temp[i * 3 + 1&& temp[i * 3 + 1== temp[i * 3 + 2]&&temp[i*3!= '.') {    //가로
            m[temp] = true;
            return;
        }
        if (temp[i] == temp[i + 3&& temp[i + 3== temp[i + 6]&&temp[i] != '.') {    //세로
            m[temp] = true;
            return;
        }
    }
    if (((temp[0== temp[4&& temp[4== temp[8]) || (temp[2== temp[4&& temp[4== temp[6])) && temp[4!= '.') {    //대각
        m[temp] = true;
        return;
    }
 
    for (int i = 0; i < 9; i++) {
        if (temp[i] == '.') {
            if (level % 2 == 0) {
                temp[i] = 'X';
                dfs(level + 1);
                temp[i] = '.';
            }
            else {
                temp[i] = 'O';
                dfs(level + 1);
                temp[i] = '.';
            }
        }
    }
}
 
int main()
{
    dfs(0);    //가능한 경우의수 map에 저장
 
    while (1) {
        scanf("%s"&tik);
        if (!strcmp(tik, "end")) {
            return 0;
        }
 
        if (m[tik] == true) {
            printf("valid\n");
        }
        else {
            printf("invalid\n");
        }
    }
}
cs
반응형
반응형

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

 

2636번: 치즈

아래 <그림 1>과 같이 정사각형 칸들로 이루어진 사각형 모양의 판이 있고, 그 위에 얇은 치즈(회색으로 표시된 부분)가 놓여 있다. 판의 가장자리(<그림 1>에서 네모 칸에 X친 부분)에는 치즈가 놓

www.acmicpc.net

 

 

[ 문제풀이 ]

 

1. 바깥쪽의 공기를 bfs를 이용하여 찾아줍니다.

 

2. 치즈를 for문을 통해 돌면서 공기 중에 노출되어 있다면 녹입니다.

 

3. 녹이기 전 치즈의 개수를 세어서 ans에 넣습니다.

 

4. 만약 치즈의 개수가 0개라면 흐른 시간과 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
#include<iostream>
#include<queue>
#include<cstring>
 
using namespace std;
 
int N, M;
int arr[100][100];
int dy[4= { -1,1,0,0 };
int dx[4= { 0,0,-1,1 };
int temp[100][100];
int visited[100][100];
int ans;
int ansC;
 
bool check(int y, int x)    //공기 중에 노출 된 치즈 찾기
{
    for (int i = 0; i < 4; i++) {
        int yy = y + dy[i];
        int xx = x + dx[i];
 
        if (temp[yy][xx] == 2) {
            return true;
        }
    }
 
    return false;
}
 
void bfs()        //공기를 찾는 bfs
{
    queue<pair<intint>> q;
    q.push({ 0,0 });
    memset(temp, 0sizeof(temp));
    memset(visited, 0sizeof(visited));
    temp[0][0= 2;
    visited[0][0= 1;
 
    while (!q.empty()) {
        int y = q.front().first;
        int x = q.front().second;
        q.pop();
 
        for (int i = 0; i < 4; i++) {
            int yy = y + dy[i];
            int xx = x + dx[i];
 
            if (yy >= 0 && yy < N && xx >= 0 && xx < M) {
                if (arr[yy][xx] == 0 && visited[yy][xx] != 1) {
                    visited[yy][xx] = 1;
                    temp[yy][xx] = 2;
                    q.push({ yy,xx });
                }
            }
        }
    }
}
 
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]);
        }
    }
 
    while (1) {
        bfs();
        int cnt = 0;
 
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                if (arr[i][j] == 1) {
                    cnt++;
                    if (check(i, j)) {
                        temp[i][j] = 1;
                    }
                }
            }
        }
 
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                if (temp[i][j] == 1) {
                    arr[i][j] = 0;
                }
            }
        }
        
        if (cnt == 0) {
            printf("%d\n%d", ansC, ans);
            return 0;
        }
 
        ans = cnt;
        ansC++;
    }
}
cs
반응형
반응형

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

 

3954번: Brainf**k 인터프리터

각 테스트 케이스에 대해서, 프로그램이 종료된다면 "Terminates"를, 무한 루프에 빠지게 된다면 "Loops"를 출력한다. 무한 루프에 빠졌을 때는, 프로그램의 어느 부분이 무한 루프인지를 출력한다. ([

www.acmicpc.net

 

 

[ 문제풀이 ]

 

1. 각각의 브라켓의 쌍을 저장할 수 있도록 map을 선언합니다.

 

2. stack을 사용하여 ' [ '를 만나면 stack에 현재 idx를 push 하고, ' ] '를 만나면 stack의 top과 쌍이므로 map [ i ] = stack.top(), map [ stack.top() ] = i를 저장해줍니다.

 

3. 5천만번 반복했을 때 무한 루프 안이거나 프로그램은 항장 종료되어 있기 때문에 5천만 번 반복 후에도 끝나지 않으면 무조건 무한 루프 안입니다.

 

4. 5천 만번 실행 후 한번 더 5천만 번 실행하면서 무한 루프 안이므로 도달한 최대 idx를 max에 저장하고 그에 맞는 쌍을 출력해주면 됩니다.

 

[ 소스코드 ]

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
#include<iostream>
#include<stack>
#include<map>
#include<cstring>
 
#define M 256
 
using namespace std;
 
unsigned char arr[100000];
char cal[4097];
char input[4097];
 
int main()
{
    int T;
    scanf("%d"&T);
 
    for (int t = 0; t < T; t++) {
        int sm, sc, si;
        scanf("%d %d %d"&sm, &sc, &si);
        
        stack<int> s;
        map<intint> m;
        memset(arr, 0sizeof(arr));
        scanf("%s", cal);
        scanf("%s", input);
 
        for (int i = 0; i < sc; i++) {
            if (cal[i] == '[') {
                s.push(i);
            }
            if (cal[i] == ']') {
                int temp = s.top();
                s.pop();
                m[temp] = i;
                m[i] = temp;
            }
        }
 
        int cnt = 0;    //연산 횟수
        int cur = 0;    //현재 포이터 위치
        int c = 0;        //현재 연산의 위치
        int in = 0;        //현재 문자열의 위치
        int Max = 0;
 
        while (1) {
            if (cnt > 50000000) {
                Max = max(Max, c);
            }
            if (cal[c] == '+') {
                arr[cur]++;
            }
            else if (cal[c] == '-') {
                arr[cur]--;
            }
            else if (cal[c] == '<') {
                cur--;
                if (cur < 0) {
                    cur = sm - 1;
                }
            }
            else if (cal[c] == '>') {
                cur++;
                if (cur >= sm) {
                    cur = 0;
                }
            }
            else if (cal[c] == '[') {
                if (arr[cur] == 0) {
                    c = m[c];
                }
            }
            else if (cal[c] == ']') {
                if (arr[cur] != 0) {
                    c = m[c];
                }
            }
            else if (cal[c] == ',') {
                if (in < si) {
                    arr[cur] = input[in++];
                }
                else {
                    arr[cur] = 255;
                }
            }
            c++;
            cnt++;
            if (c >= sc) {
                printf("Terminates\n");
                break;
            }
            if (cnt >= 100000000) {
                printf("Loops %d %d\n", m[Max], Max);
                break;
            }
        }
    }
}
cs
반응형
반응형

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

 

17472번: 다리 만들기 2

첫째 줄에 지도의 세로 크기 N과 가로 크기 M이 주어진다. 둘째 줄부터 N개의 줄에 지도의 정보가 주어진다. 각 줄은 M개의 수로 이루어져 있으며, 수는 0 또는 1이다. 0은 바다, 1은 땅을 의미한다.

www.acmicpc.net

 

 

[ 문제풀이 ]

 

1. 각 섬에 번호를 매기고 각 번호마다 섬의 좌표를 vector에 저장합니다.

 

2. 모든 섬을 2중 for문을 사용하여 서로 간의 최소 거리를 list vector에 저장합니다.

 

3. pq에 출발점, 도착점과 거리를 넣습니다.

 

4. pq에서 하나씩 뽑아서 크루스칼 알고리즘을 통해  MST를 찾아줍니다.

 

5. 모든 섬을 2중 for문을 사용하여 루트 노드가 다른 섬이 하나라도 있다면 -1을 출력해줍니다.

 

6. 그렇지 않다면 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
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
#include<iostream>
#include<vector>
#include<queue>
 
using namespace std;
 
int N, M;
int arr[10][10];
int visited[10][10];
int dy[4= { -1,1,0,0 };
int dx[4= { 0,0,-1,1 };
vector<pair<intint>> pos[7];
vector<pair<intint>> list[7];
int vect[7];
 
struct node {    
    int start;
    int end;
    int dist;
};
 
struct cmp {
    bool operator()(node right, node left) {
        return left.dist < right.dist;
    }
};
 
int find(int num)    //부모 찾기
{
    if (vect[num] == num) return num;
    return vect[num] = find(vect[num]);
}
 
void Union(int a, int b)    //같은 부모를 가지고 있는지
{
    int pa = find(a);
    int pb = find(b);
 
    vect[pb] = pa;
}
 
void getDist(int a, int b) //두 섬 사이의 최단 거리 구하기
{
    int ret = 987654321;
 
    for (auto A : pos[a]) {
        for (auto B : pos[b]) {
            if (A.first == B.first) {
                bool flag = false;
                if (A.second > B.second) {
                    for (int i = B.second + 1; i < A.second; i++) {
                        if (arr[A.first][i] == 1) {
                            flag = true;
                            break;
                        }
                    }
                    if (flag == false) {
                        if (A.second - B.second - 1 != 1) {
                            ret = min(ret, A.second - B.second - 1);
                        }
                    }
                }
                else {
                    for (int i = A.second + 1; i < B.second; i++) {
                        if (arr[A.first][i] == 1) {
                            flag = true;
                            break;
                        }
                    }
                    if (flag == false) {
                        if (B.second - A.second - 1 != 1) {
                            ret = min(ret, B.second - A.second - 1);
                        }
                    }
                }
            }
            if (A.second == B.second) {
                bool flag = false;
                if (A.first > B.first) {
                    for (int i = B.first + 1; i < A.first; i++) {
                        if (arr[i][A.second] == 1) {
                            flag = true;
                            break;
                        }
                    }
                    if (flag == false) {
                        if (A.first - B.first - 1 != 1) {
                            ret = min(ret, A.first - B.first - 1);
                        }
                    }
                }
                else {
                    for (int i = A.first + 1; i < B.first; i++) {
                        if (arr[i][A.second] == 1) {
                            flag = true;
                            break;
                        }
                    }
                    if (flag == false) {
                        if (B.first - A.first - 1 != 1) {
                            ret = min(ret, B.first - A.first - 1);
                        }
                    }
                }
            }
        }
    }
 
    if (ret != 987654321) {
        list[a].push_back({ b,ret });
    }
}
 
void bfs(int y, int x, int cnt)    //이어져 있는 땅 찾기
{
    queue<pair<intint>> q;
    q.push({ y,x });
    visited[y][x] = 1;
    pos[cnt].push_back({ y,x });
 
    while (!q.empty()) {
        int y = q.front().first;
        int x = q.front().second;
        q.pop();
 
        for (int i = 0; i < 4; i++) {
            int yy = y + dy[i];
            int xx = x + dx[i];
            if (yy >= 0 && yy < N && xx >= 0 && xx < M) {
                if (visited[yy][xx] != 1 && arr[yy][xx] == 1) {
                    visited[yy][xx] = 1;
                    q.push({ yy,xx });
                    pos[cnt].push_back({ yy,xx });
                }
            }
        }
    }
}
 
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]);
        }
    }
    
    int cnt = 1;
 
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (arr[i][j] == 1 && visited[i][j] != 1) {
                bfs(i, j, cnt);
                cnt++;
            }
        }
    }
 
    cnt;
 
    for (int i = 1; i < cnt; i++) {
        vect[i] = i;
        for (int j = 1; j < cnt; j++) {
            if (i != j) {
                getDist(i, j);
            }
        }
    }
 
    priority_queue<node, vector<node>, cmp> pq;
 
    for (int i = 1; i < cnt; i++) {
        for (auto next : list[i]) {
            pq.push({ i,next.first,next.second });
        }
    }
 
    int ans = 0;
 
    while (!pq.empty()) {
        int start = pq.top().start;
        int end = pq.top().end;
        int dist = pq.top().dist;
        pq.pop();
 
        if (find(start) != find(end)) {
            Union(start, end);
            ans += dist;
        }
    }
 
    for (int i = 1; i < cnt; i++) {
        for (int j = 1; j < cnt; j++) {
            if (i != j) {
                if (find(i) != find(j)) {
                    printf("%d"-1);
                    return 0;
                }
            }
        }
    }
 
    printf("%d", ans);
}
cs
반응형

+ Recent posts