블로그 이미지
shadowchaser
이곳 저곳 이것 저것

calendar

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

Notice

'Algorithm'에 해당되는 글 26

  1. 2016.03.20 토마토(고)
  2. 2016.03.12 bubble sort
  3. 2016.02.27 default
  4. 2016.02.25 단지번호 붙이기 - 정올 1695번2
  5. 2016.02.16 NQueen - 정올 1889번
  6. 2016.02.14 단지번호 붙이기
2016. 3. 20. 20:11 Algorithm/BFS

토마토 (고)


#include <stdio.h>

#include <stdlib.h>


int M, N;

int map[1000][1000];


typedef struct {

int row;

int col;

int day;

} _COORDI;

int head = 0, tail = 0;

_COORDI point[1000000];


int Dy[4] = { -1,1,0,0 };

int Dx[4] = { 0,0,-1,1 };

int min = 0;


int bfs(int row, int col)

{

int i;

int row_t, col_t;


while (1)

{

if (head == tail) break;

for (i = 0; i < 4; i++)

{

row_t = point[head].row + Dy[i];

col_t = point[head].col + Dx[i];

if (row_t >= 0 && row_t < N && col_t >= 0 && col_t < M)

{

if (map[row_t][col_t] == 0)

{

map[row_t][col_t] = 1;

point[tail].row = row_t;

point[tail].col = col_t;

point[tail].day = point[head].day + 1;

tail++;

}

}

}

head++;

}


return point[head - 1].day;

}


int main(int argv, char** argc) {

freopen("input.txt", "r", stdin);

setbuf(stdout, NULL);

scanf("%d %d", &M, &N);

for (int i = 0; i < N; i++)

{

for (int j = 0; j < M; j++)

{

scanf("%d", &map[i][j]);

if (map[i][j] == 1)

{

point[tail].row = i;

point[tail].col = j;

point[tail].day = 0;

tail++;

}

}

}


if (tail == 0)

{

printf("-1\n");

return 0;

}


if (tail == M * N)

{

printf("0\n");

return 0;

}


min = bfs(0, 0);

int find = 0;


for (int i = 0; i < N; i++)

{

for (int j = 0; j < M; j++)

{

if (map[i][j] == 0)

{

find = 1;

break;

}

}

}

if (find == 1)

{

printf("-1\n");

}

else

{

printf("%d\n", min);

}

return 0;//정상종료시 반드시 0을 리턴해야합니다.

}



'Algorithm > BFS' 카테고리의 다른 글

정올 등산로 찾기  (0) 2016.06.17
정올 저글링 방사능 오염  (0) 2016.06.15
정올 보물섬  (0) 2016.05.21
정올 장기  (0) 2016.05.09
정올 치즈 BFS  (0) 2016.04.04
posted by shadowchaser
2016. 3. 12. 00:32 Algorithm/기본 이론

다른 곳의 bubble sort는 잘못된 곳이 많다.


특히,10-i-1의 위치가 잘못된 곳이 많다. 

int main()

{

int arr[10] = { 3, 7, 4, 8, 6, 2, 13, 1, 9 ,5 };

for (int i = 0; i < 10 - 1; i++)

{

for (int j = 0; j < 10 - i - 1; j++)

{

int tmp;

if (arr[j] > arr[j + 1])

{

tmp = arr[j + 1];

arr[j + 1] = arr[j];

arr[j] = tmp;

}

}

}

'Algorithm > 기본 이론' 카테고리의 다른 글

순열, 중복순열, 조합, 중복조합  (0) 2016.08.06
정올 지하철  (0) 2016.07.23
공부 순서  (0) 2016.06.13
default  (0) 2016.02.27
posted by shadowchaser
2016. 2. 27. 01:27 Algorithm/기본 이론

#include <stdio.h>

 

int n; // 정점의 총 갯수

int map[30][30], visit[30]; // 인접 행렬과 방문 여부를 나타내는 배열

 

void DFS(int v)

{

    int i;

 

    visit[v] = 1; // 정점 v를 방문했다고 표시

    for (i = 1; i <= n; i++) 

    {

        // 정점 v와 정점 i가 연결되었고, 정점 i를 방문하지 않았다면

        if (map[v][i] == 1 && !visit[i])

        {

            printf("%d에서 %d로 이동\n", v, i);

            // 정점 i에서 다시 DFS를 시작한다

            DFS(i);

        }

    }

}

 

int main()

{

    int start; // 시작 정점

    int v1, v2;

 

    scanf("%d%d", &n, &start);

 

    while (1)

    {

        scanf("%d%d", &v1, &v2);

        if (v1 == -1 && v2 == -1) break; // -1과 -1이 입력되면 무한 루프 탈출

        map[v1][v2] = map[v2][v1] = 1; // 정점 v1과 정점 v2가 연결되었다고 표시

    }

    DFS(start); // DFS 시작!

 

    return 0;

}


===================================================================================================

#include<stdio.h>


int n, min;

int map[10][10];

int count;


/*

5

1 1 1 1 1

0 0 0 0 1

1 1 1 1 1

1 0 1 0 0

1 1 1 1 1


*/

void DFS(int x, int y, int l)

{

if (x == n - 1 && y == n - 1)

{

count++;

return;

}


map[y][x] = 0; 

// 위로 이동 가능?

if (y > 0 && map[y - 1][x]) DFS(x, y - 1, l + 1);

if (y < n-1 && map[y + 1][x]) DFS(x, y + 1, l + 1);

if (x > 0 && map[y][x - 1]) DFS(x -1 , y , l + 1);

if (x < n-1 && map[y][x + 1]) DFS(x +1, y , l + 1);


map[y][x] = 1;

}

int main()

{

int i, j;


scanf("%d", &n);

min = n * n; // 모든 경로를 돌아다녀도 n * n이니, 이를 최소값으로 지정해둔다

for (i = 0; i < n; i++)

for (j = 0; j < n; j++)

scanf("%d", &map[i][j]);

DFS(0, 0, 1); // DFS 시작!


printf("최단 거리: %d\n", min);


return 0;

}

===================================================================================================

#include <stdio.h>

 

int n; // 입력되는 정점의 최댓값

int rear, front; // 전단과 후단을 나타내는 변수

int map[30][30], queue[30], visit[30]; // 인접 행렬과 큐와 방문 배열

 

void BFS(int v)

{

    int i;

 

    visit[v] = 1; // 정점 v를 방문했다고 표시

    printf("%d에서 시작\n", v);

    queue[rear++] = v; // 큐에 v를 삽입하고 후단을 1 증가시킴

    while (front < rear) // 후단이 전단과 같거나 작으면 루프 탈출

    {

        // 큐의 첫번째에 있는 데이터를 제외하고 제외된 값을 가져오며, 전단 1 증가

        v = queue[front++];

        for (i = 1; i <= n; i++)

        {

            // 정점 v와 정점 i가 만나고, 정점 i를 방문하지 않은 상태일 경우

            if (map[v][i] == 1 && !visit[i])

            {

                visit[i] = 1; // 정점 i를 방문했다고 표시

                printf("%d에서 %d로 이동\n", v, i);

                queue[rear++] = i; // 큐에 i를 삽입하고 후단을 1 증가시킴

            }

        }

    }

}

 

int main()

{

    int start; // 시작 정점을 나타내는 변수

    int v1, v2;

 

    scanf("%d%d", &n, &start);

 

    while (1)

    {

        scanf("%d%d", &v1, &v2);

        if (v1 == -1 && v2 == -1) break;

        map[v1][v2] = map[v2][v1] = 1;

    }

    BFS(start); // BFS 시작!

 

    return 0; 

}

===================================================================================================

#include <stdio.h>

 

int n, cnt; // 맵의 크기와 카운트 변수

int map[10][10]; // 맵을 나타내는 2차원 배열

int x[100], y[100], l[100]; // 좌표와 길이를 담을 배열

 

// 큐에 좌표 정보와 길이를 삽입하는 함수

void enqueue(int _x, int _y, int _l)

{

    x[cnt] = _x;

    y[cnt] = _y;

    l[cnt] = _l;

    cnt++;

}

 

void BFS(int _x, int _y)

{

    int pos = 0;

 

    // 시작점의 좌표 정보와 길이를 큐에 삽입한다

    enqueue(_x, _y, 1);

    // 더 이상 방문할 지점이 없거나, 도착 지점에 도착하면 루프를 탈출한다

    while (pos < cnt && (x[pos] != n - 1 || y[pos] != n - 1))

    {

        // 두 번 방문하게 하면 안되므로, 이미 지나갔다는 표시를 해둔다

        map[y[pos]][x[pos]] = 0;

 

        // 위로 갈 수 있다면, 위 지점의 좌표 정보와 길이를 큐에 삽입한다

        if (y[pos] > 0 && map[y[pos] - 1][x[pos]] == 1)

            enqueue(x[pos], y[pos] - 1, l[pos] + 1);

        // 아래로 갈 수 있다면, 아래 지점의 좌표 정보와 길이를 큐에 삽입한다

        if (y[pos] < n - 1 && map[y[pos] + 1][x[pos]] == 1)

            enqueue(x[pos], y[pos] + 1, l[pos] + 1);

        // 왼쪽으로 갈 수 있다면, 왼쪽 지점의 좌표 정보와 길이를 큐에 삽입한다

        if (x[pos] > 0 && map[y[pos]][x[pos] - 1] == 1)

            enqueue(x[pos] - 1, y[pos], l[pos] + 1);

        // 오른쪽로 갈 수 있다면, 오른쪽 지점의 좌표 정보와 길이를 큐에 삽입한다

        if (x[pos] < n - 1 && map[y[pos]][x[pos] + 1] == 1)

            enqueue(x[pos] + 1, y[pos], l[pos] + 1);

 

        // 큐의 다음 순서의 지점을 방문한다

        pos++;

    }

 

    // cnt가 pos보다 크다면, 도착 지점에 무사히 도착한 것이라고 말할 수 있다.

    // 위의 반복문은 도착점에 도착하게 되면 루프를 바로 빠져나오기 때문에,

    // 길이를 삽입하는 큐의 마지막 요소가 최단 경로의 길이라고 할 수 있다.

    if (pos < cnt)

        printf("최단 경로 길이: %d\n", l[pos]);

}

 

int main()

{

    int i, j;

 

    scanf("%d", &n);

    min = n * n;

    for (i = 0; i < n; i++)

        for (j = 0; j < n; j++)

            scanf("%d", &map[i][j]);

    BFS(0, 0); // BFS 시작!

 

    return 0;

}

=================

#include<stdio.h>


int N;

int scan[30][30];

int Ndanji = 2;

int sol[1000] = { 0, };

int cnt = 1;

void danji(int x, int y)

{

scan[x][y] = Ndanji;

if (scan[x][y + 1] == 1) { cnt++; danji(x, y + 1); }

if (scan[x][y - 1] == 1) { cnt++; danji(x, y - 1); }

if (scan[x - 1][y] == 1) { cnt++; danji(x - 1, y); }

if (scan[x + 1][y] == 1) { cnt++; danji(x + 1, y); }

}

void main()

{

scanf("%d", &N);


for (int i = 0; i < N; i++)

{

for (int j = 0; j < N; j++)

{

scanf("%1d", &scan[i][j]);

}

}


for (int i = 0; i < N; i++)

{

for (int j = 0; j < N; j++)

{

if (scan[i][j] == 1)

{

danji(i, j);

sol[Ndanji] = cnt;

Ndanji++;

cnt = 1;

}


}

}


int tmp;

for (int i = 0; i < Ndanji; i++)

{

for (int j = 0; j < Ndanji -1-i; j++)

{

if (sol[j] > sol[j + 1])

{

tmp = sol[j];

sol[j] = sol[j+1];

sol[j+1] = tmp;

}

}

}


printf("%d\n", Ndanji-2);

for (int i = 2; i < Ndanji; i++)

{

printf("%d\n", sol[i]);

}

}

'Algorithm > 기본 이론' 카테고리의 다른 글

순열, 중복순열, 조합, 중복조합  (0) 2016.08.06
정올 지하철  (0) 2016.07.23
공부 순서  (0) 2016.06.13
bubble sort  (0) 2016.03.12
posted by shadowchaser
2016. 2. 25. 00:26 Algorithm/DFS

전형적인 DFS인 단지번호 붙이기는 DFS 로직만 알고 있다면 쉽게 접근할 수 있다.

단지번호 붙이기는 그냥 숫자만 올리고, 정렬하는 것만 유의하면 된다.


특히 bubble sort를 진행할 때 어떤 블로그들에선 완전히 잘못된 내용으로 접근하는 경우가 있다. 비교를 정말 쓸데 없는 부분까지 하는경우가 있는데,


https://ko.wikipedia.org/wiki/%EA%B1%B0%ED%92%88_%EC%A0%95%EB%A0%AC에 나와있는 바처럼 짧게 기술할 수 있다.


암튼 결론은 버킹검



'Algorithm > DFS' 카테고리의 다른 글

DFS 정복!! 레벨 별  (0) 2016.06.22
예산 관리  (0) 2016.06.18
정올 더하기  (0) 2016.06.17
NQueen - 정올 1889번  (0) 2016.02.16
단지번호 붙이기  (0) 2016.02.14
posted by shadowchaser
2016. 2. 16. 00:18 Algorithm/DFS

정올 1889번 NQueen문제의 답

http://www.jungol.co.kr/bbs/board.php?bo_table=pbank&wr_id=1162&sca=3030

backtracking을 활용한 것이다.

backtracking이란.. dfs를 통해 구현하는 중에 가지치기를 진행하는 수법이라고 한다.


#include <stdio.h>

#include <stdlib.h> //abs 함수를 사용하기 위해서임


int promising(int); // 할만한지 안한지 체크하는 함수. 

int n;

int col[255] = { 0, }; // 행에 놓이는 값. 예를 들어 col[1] = 5라면 2번째 에는 5번째에 있다는 내용임

int cnt =0; // 해결되는 값


void queens(int i) {

if (promising(i))

{

if (i == n)

{

cnt++; // 총 개수를 구함

}

else

{

for (int j = 1; j <= n; j++) {

col[i + 1] = j;

queens(i + 1);

}

}

}

}


int promising(int i) { // 직선, 대각선으로 만나는지 검사

int k = 1, promising = 1;

while (k < i && promising) {

if (col[i] == col[k] || abs(col[i] - col[k]) == abs(i - k)) //직선이나 대각선상에 있는가를 검사

{

promising = 0;

}

k++;

}

return promising;

}


int main() {

scanf("%d", &n);

queens(0);

printf("%d", cnt);

}



'Algorithm > DFS' 카테고리의 다른 글

DFS 정복!! 레벨 별  (0) 2016.06.22
예산 관리  (0) 2016.06.18
정올 더하기  (0) 2016.06.17
단지번호 붙이기 - 정올 1695번  (2) 2016.02.25
단지번호 붙이기  (0) 2016.02.14
posted by shadowchaser
2016. 2. 14. 23:28 Algorithm/DFS

단지번호 붙이기


#include <stdio.h>


/*

7

0 1 1 0 1 0 0

0 1 1 0 1 0 1

1 1 1 0 1 0 1

0 0 0 0 1 1 1

0 1 0 0 0 0 0 

0 1 1 1 1 1 0

0 1 1 1 0 0 0


*/

#include<stdio.h>


int N;

int map[100][100] = { 0, };

void dfs(int sero, int garo, int cnt)

{

map[sero][garo] = cnt;

if (sero - 1 >= 0 && map[sero - 1][garo] == 1) { 

dfs(sero - 1, garo, cnt); }

if (sero + 1 < N && map[sero + 1][garo] == 1) { 

dfs(sero + 1, garo, cnt); }

if (garo - 1 >= 0 && map[sero][garo - 1] == 1) { 

dfs(sero, garo - 1, cnt); }

if (garo + 1 < N && map[sero][garo + 1] == 1) { 

dfs(sero, garo + 1, cnt); }

}

void main()

{

freopen("input.txt", "r", stdin);

scanf("%d", &N);

for (int i = 0; i < N; i++)

{

for (int j = 0; j < N; j++)

{

scanf("%1d", &map[i][j]);

}

}


int cnt = 1;

for (int i = 0; i < N; i++)

{

for (int j = 0; j < N; j++)

{

if (map[i][j] == 1)

{

cnt++;

dfs(i, j, cnt);

}

}

}


int Area[100] = { 0, };

int tmp = cnt - 1;

int k = 2;

for (int i = 0; i<N; i++)

{

for (int j = 0; j<N; j++)

{

if (map[i][j])

{

Area[map[i][j] - 2]++;

}

}

}

for (int i = 0; i< cnt -2; i++)

{

for (int j = 0; j< cnt-2-i; j++)

{

if (Area[j] > Area[j + 1])

{

int tmp = Area[j + 1];

Area[j + 1] = Area[j];

Area[j] = tmp;

}

}

}

printf("%d\n", cnt-1);

for (int i = 0; i < cnt - 1; i++)

{

printf("%d\n", Area[i]);

}

}

'Algorithm > DFS' 카테고리의 다른 글

DFS 정복!! 레벨 별  (0) 2016.06.22
예산 관리  (0) 2016.06.18
정올 더하기  (0) 2016.06.17
단지번호 붙이기 - 정올 1695번  (2) 2016.02.25
NQueen - 정올 1889번  (0) 2016.02.16
posted by shadowchaser
prev 1 2 3 next