[백준 2309번 일곱 난쟁이]

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>
#include <vector>
#include <algorithm>
using namespace std;
 
vector<int> picked;
vector<int> smallMan;
bool finish = true;
void findSmallMan(vector<int>& picked, int start ,int tallSum)
{
    if (finish == falsereturn;    // 기저사례. 이미 1번 출력했다면 함수를 빠져나온다.
    if (picked.size() == 7)
    {
        if (tallSum == 100)
        {
            sort(picked.begin(), picked.end());
            for (int i = 0; i < 7; i++)
                cout << picked[i] << endl;
            finish = false;
        }
    }
    for (int i = start; i < 9; i++)    // 순서만 다른 조합을 배제하기 위해 start부터 시작
    {
        picked.push_back(smallMan[i]);
        findSmallMan(picked, i + 1, tallSum + smallMan[i]);
        picked.pop_back();
    }
}
int main(void)
{
    for (int i = 0; i < 9; i++)
    {
        int tall;
        cin >> tall;
        smallMan.push_back(tall);
    }
    findSmallMan(picked, 00);
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter

알고리즘 200일 프로젝트 - 5day

원소의 수가 9개로 제한되어 있기때문에 완전탐색 알고리즘을 적용하여 간단하게 해결할 수 있는 문제였다.

 

'알고리즘 > BOJ' 카테고리의 다른 글

백준 6603번: 로또  (0) 2020.04.12
백준 7568번: 덩치  (0) 2020.04.11
백준 14502번: 연구소  (0) 2020.04.11
백준 2231번: 분해합  (0) 2020.04.11
백준 14501번: 퇴사  (0) 2020.04.10

출처: 알고스팟

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
#include <iostream>
#include <vector>
using namespace std;
 
#define INF 987654321
 
vector<vector<int> > switch_list({        // 스위치와 연결된 시계
    vector<int>({ 012 }),
    vector<int>({ 37911 }),
    vector<int>({ 4101415 }),
    vector<int>({ 04567 }),
    vector<int>({ 6781012 }),
    vector<int>({ 021415 }),
    vector<int>({ 31415 }),
    vector<int>({ 4571415 }),
    vector<int>({ 12345 }),
    vector<int>({ 345913 })
    });
 
int min(int a, int b) { return a < b ? a : b; }
 
void SetTheClock(vector<int>& watch, int swtch)
{
    int n = switch_list[swtch].size();
    for (int i = 0; i < n; i++)
    {
        watch[switch_list[swtch][i]] += 3;
        if (watch[switch_list[swtch][i]] > 12)
            watch[switch_list[swtch][i]] = 3;
    }
}
 
int twelveOclock(vector<int>& watch, int swtch)
{
    if (swtch == 10)
    {
        for (int i = 0; i < 16; i++)
            if (watch[i] != 12return INF;
        return 0;
    }
    int ret = INF;
    for (int cnt = 0; cnt < 4; cnt++)
    {
        ret = min(ret, cnt + twelveOclock(watch, swtch+1));    // 시계 돌려돌려
        SetTheClock(watch, swtch);
    }
    return ret;
}
 
int main(void)
{
    int testcase;
    vector<int> watch;
    cin >> testcase;
    while (testcase--)
    {
        for (int i = 0; i < 16; i++)
        {
            int time;
            cin >> time;
            watch.push_back(time);
        }
        int res = twelveOclock(watch, 0);
        if (res == INF) cout << -1 << endl;
        else cout << res << endl;
        watch.clear();
    }
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter

알고리즘 200일 프로젝트 - 4day

알고리즘 문제해결 전략 6.8 시계 맞추기(ID:CLOCKSYNC)

난이도 중짜리 문제였지만 내가 생각한 아이디어와 책에서 제시한 풀이법이 같아서 뿌듯했다.

하지만 시계를 4번 움직였을 때 제자리로 돌아온다는 점을 생각은 했으나 문제의 핵심포인트라는 것까지는 생각하지 못하여 원하는 출력결과를 얻지못하였다. 성급하게 구현하는 나쁜습관을 고치도록 노력해야겠다.

또한 아무리 들여봐도 알 수없는 버그때문에 골머리를 앓았는데 그 원인은 허무하게도 첫줄의 벡터배열을 잘못된 방법으로 선언함으로써 발생한 버그였다.

종만북 공부를 잠시 중단하고 effective c++과 뇌를 자극하는 c++ STL 두 권을 먼저 공부 한다음 다시 펼쳐봐야겠다.

내일도 열심히!

 
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
#include <iostream>
#include <vector>
using namespace std;
int cnt;
const int coverType[4][3][2= {
    {{0,0}, {0,1}, {1,1}},    // 블록이 회전하는 4가지 형태 
    {{0,0}, {1,0}, {1,1}},
    {{0,0}, {1,0}, {1,-1}},
    {{0,0}, {0,1}, {1,0}}
};
bool set(vector<vector<int> >& board, int y, int x, int type, int delta)
{
    bool state = true;
    for (int i = 0; i < 3; i++)
    {
        int colMax = board.size();
        int rowMax = board[0].size();
        const int ny = y + coverType[type][i][0];
        const int nx = x + coverType[type][i][1];
        if (ny < 0 || ny >= colMax ||
            nx < 0 || nx >= rowMax)
            state = false;
        else if ((board[ny][nx] += delta) > 1)    // delta = 1 일 때, 블록을 덮는다. 
            state = false;                        // delta = -1 일 때, 블록을 치운다. 
    }
    return state;
}
int Solution(vector<vector<int> >& board)
{
    if (cnt % 3 != 0return 0;    // 기저 사례. 비어이는 블록의 수가 3의 배수가 아닐 경우 반드시 실패
    int col = -1, row = -1;
    int colMax = board.size();    // 행 길이
    int rowMax = board[0].size();    // 열 길이
    for (int i = 0; i < colMax; i++)
    {
        for (int j = 0; j < rowMax; j++)    // 비어있는 칸 중 좌측 상단을 먼저 
        {
            if (board[i][j] == 0)
            {
                col = i;
                row = j;
                break;
            }
        }
        if (col != -1break;    // 2중 for문 탈출 
    }
    if (col == -1return 1;    // 기저 사례. 비어있는 칸이 없으므로 1 증가
    int ret = 0;
    for (int i = 0; i < 4; i++)
    {
        if (set(board, col, row, i, 1))    // 비어있는 칸에 블록을 맞춰본다 
            ret += Solution(board);
        set(board, col, row, i, -1);
    }
    return ret;
}
int main(void)
{
    int testcase;
    cin >> testcase;
    while (testcase--)
    {
        int a, b;
        cin >> a >> b;
        vector<vector<int>> board(a);
        cnt = 0;
        for (int i = 0; i < a; i++)
        {
            for (int j = 0; j < b; j++)
            {
                char block;
                cin >> block;
                if (block == '#')    // 막힌 칸을 1로 치환 
                    board[i].push_back(1);
                else if (block == '.')    // 비어있는 칸을 0으로 치환 
                {
                    board[i].push_back(0);
                    cnt++;
                }
            }
        }
        cout << Solution(board) << endl;
        board.clear();
    }
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
 
 

 

 

알고리즘 200일 프로젝트 - 4day

알고리즘 문제해결 전략 6.5 게임판 덮기(ID:BOARDCOVER)

피크닉 문제에서 적용한 재귀함수와 유사한 형태로 구현할 수 있는 문제였다.

내가 생각한 아이디어와 책에서 제시한 아이디어의 접근방법은 비슷했으나,

중복을 신경쓰지 못하여 원하는 출력을 얻지 못하였다. 꾸준히 복습하여 내것으로 만들도록 해야겠다. 

내일도 열심히!

 

 

문제

안드로메다 유치원 익스프레스반에서는 다음 주에 율동공원으로 소풍을 갑니다. 원석 선생님은 소풍 때 학생들을 두 명씩 짝을 지어 행동하게 하려고 합니다. 그런데 서로 친구가 아닌 학생들끼리 짝을 지어 주면 서로 싸우거나 같이 돌아다니지 않기 때문에, 항상 서로 친구인 학생들끼리만 짝을 지어 줘야 합니다.

각 학생들의 쌍에 대해 이들이 서로 친구인지 여부가 주어질 때, 학생들을 짝지어줄 수 있는 방법의 수를 계산하는 프로그램을 작성하세요. 짝이 되는 학생들이 일부만 다르더라도 다른 방법이라고 봅니다. 예를 들어 다음 두 가지 방법은 서로 다른 방법입니다.

  • (태연,제시카) (써니,티파니) (효연,유리)
  • (태연,제시카) (써니,유리) (효연,티파니)

입력

입력의 첫 줄에는 테스트 케이스의 수 C (C <= 50) 가 주어집니다. 각 테스트 케이스의 첫 줄에는 학생의 수 n (2 <= n <= 10) 과 친구 쌍의 수 m (0 <= m <= n*(n-1)/2) 이 주어집니다. 그 다음 줄에 m 개의 정수 쌍으로 서로 친구인 두 학생의 번호가 주어집니다. 번호는 모두 0 부터 n-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
#include <iostream>
#include <cstring>
using namespace std;
 
bool areFriend[10][10];    // 친한친구 배열
int student;    // 학생 수
int Solution(bool taken[10])
{
    int firstFree = -1;
    for (int i = 0; i < student; i++)
        if (taken[i] == false)    // i = 0~(student-1) 까지 전체 학생을 검사하여 짝을 짓지못한 학생을 찾아낸다.
        {
            firstFree = i;
            break;
        }
    if (firstFree == -1return 1;    // 학생들이 모두 짝을 이루었으므로 1 증가
    int ret = 0;    // ret : 짝을 지을수 있는 경우의 수
    for(int i=firstFree+1; i<student; i++)
        if (!taken[firstFree] && !taken[i] && areFriend[firstFree][i])
        {
            taken[firstFree] = taken[i] = true;    // 아직 짝을 짓지못한 친한 학생 taken[firstFree]와 taken[i]를
                                                // 짝을 지은 학생(true)로 갱신하여 Solution 함수를 재귀호출한다.
 
            ret += Solution(taken);    // 짝을 지은 학생들을 true처리하고 함수를 재호출한다. 
 
            taken[firstFree] = taken[i] = false// 아직 짝을 짓지못한 학생들중 taken[firstFree] 학생과 
                                                 // 친한 학생을 더 찾기위해 false로 초기화해준다.
        }
    return ret;
}
 
int main(void)
{
    int testcase;
    bool taken[10];
    cin >> testcase;
    while (testcase--)
    {
        int cpNum;
        cin >> student >> cpNum;
        memset(areFriend, falsesizeof(areFriend));    // 친한 친구 배열 false로 초기화
        memset(taken, falsesizeof(taken));    // 학생들의 상태를 false로 초기화
        while (cpNum--)
        {
            int a, b;
            cin >> a >> b;
            areFriend[a][b] = true;
            areFriend[b][a] = true;
        }
        cout << Solution(taken) << endl;;
    }
    return 0;
}
cs
 
 
 

 

알고리즘 200일 프로젝트 - 3day

알고리즘 문제해결 전략 6.3 소풍(ID:PICNIC)

난이도 하 문제였음에도 불구하고 이해하는데 매우 힘들었다. ㅠㅠ

내일도 열심히!

+ Recent posts