반응형

문제 출처

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


dfs, bfs고민하다 bfs로 푼 문제

1번 컴퓨터와 연결된 모든 컴퓨터의 갯수를 출력하는 문제이다.

dfs보다 bfs가 더 빠를 것이라 예상 되었다.

기본적으로 bfs 또는 dfs를 연습할 수 있는 문제

점점 문제를 풀수록 문제 이해를 하면 dfs bfs구현자체가 정형화 되있기 때문에 익숙해 지는 기분이다.

아직 많이 부족하다는 반증일수도....


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
#include <stdio.h>
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#define MAX 101
using namespace std;
int com;
int couple;
bool network[MAX][MAX];
bool visit[MAX];
queue<int> q;
int cnt=0;
 
void init() {
    scanf("%d"&com);
    scanf("%d"&couple);
    
    for(int i=1; i<=couple; i++) {
        int s, e;    //start end
        scanf("%d %d"&s, &e);
        network[s][e]=true;
        network[e][s]=true;
    }
}
 
void bfs(int s) {
    q.push(s);
    visit[s]=true;
 
    while(!q.empty()) {
        int s = q.front();
        q.pop();
 
        for(int i=1; i<=com; i++) {
            if(network[s][i] && network[i][s] && !visit[i]) {
                visit[i]=1;
                q.push(i);
                cnt++;
            }
        }
    }
}
 
int main(void) {
    init();
    bfs(1);
    cout<<cnt;
    return 0;
}
cs




반응형

'Algorithm' 카테고리의 다른 글

[Programmers 43165] 타겟넘버  (0) 2018.12.31
[BOJ 2644] 촌수계산  (0) 2018.12.31
[BOJ 2583] 영역구하기  (0) 2018.12.28
[TopCoder 전체탐색] 회문(Palindrome)  (0) 2018.12.20
[TopCoder 전체탐색] 암호(Cryptography)  (0) 2018.12.20
반응형

문제 출처

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


dfs로 풀이 했지만 bfs로 풀이하는게 더 좋을듯 하다. dfs는 모든 경우를 탐색할 수 있지만 계속적으로 탐색 하기 때문에 시간이 오래걸리는 단점이 존재한다. bfs풀이는 추가 업데이트를 하도록 하겠다. 

이 문제에서 가장 어려운건 맵을 그리는 거라 생각되는데 이해가 안된다면 종이에 그려보고 어떻게 for문을 돌려야 할지 생각해보면 금방 알 수 있다.

또한 눈금의 MAX값이 100이므로 결과를 나타낼 수 있는 배열은 100*100인 10000개를 선언해야 한다.


=> DFS 풀이

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
#include <cstdio>
#include <vector>
#include <algorithm>
#define MAX 100
using namespace std;
int n,m,k,result;
const int dx[] = {00-11};
const int dy[] = {1-100};
bool map[MAX][MAX];
void init() {
    scanf("%d %d %d"&n, &m, &k);
    int sx, sy, ex, ey;
    for (int i=0; i<k; i++) {
        scanf("%d %d %d %d"&sx, &sy, &ex, &ey);
        for (int y=sy; y<ey; y++) {
            for (int x=sx; x<ex; x++) {
                map[y][x]=1;
            }
        }
    }
}
bool isOutOfBoundMap(int y, int x) {
    if (x<0 || y<0 || x>=|| y>=n) return true;
    return false;
}
void dfs(int y, int x) {
    map[y][x]=1;
    result++;
    for (int i=0; i<4; i++) {
        int ny=y+dy[i];
        int nx=x+dx[i];
        if (isOutOfBoundMap(ny, nx) || map[ny][nx]) continue;
        dfs(ny, nx);
    }
}
void solve() {
    int areaCnt=0;
    vector<int> v;
    for (int y=0; y<n; y++) {
        for (int x=0; x<m; x++) {
            if (!map[y][x]) {
                ++areaCnt;
                dfs(y, x);
                v.push_back(result);
                result=0;
            }
        }
    }
    printf("%d\n", areaCnt);
    sort(v.begin(), v.end());
    for (int i=0; i<v.size(); i++) {
        printf("%d ", v[i]);
    }
}
int main() {
    init();
    solve();
    return 0;
}
cs


=> BFS 풀이

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
#include <stdio.h>
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#define MAX 100
 
using namespace std;
int n,m,k;
int section=0;
bool map[MAX][MAX];
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
queue<pair<intint> > q;
vector<int> ret;
 
void init() {
    scanf("%d %d %d"&n, &m, &k);
    while(k--)
    {
        int x1,x2,y1,y2;
        scanf("%d %d %d %d"&x1, &y1, &x2, &y2);
        for(int i=y2-1; i>=y1; i--)
            for(int j=x2-1; j>=x1; j--)
                map[i][j]=1;
    }
}
 
void bfs(int x, int y) {
    int cnt=1;
    map[x][y]=1;
    q.push(make_pair(x,y));
 
    while(!q.empty()) {
        x=q.front().first;
        y=q.front().second;
        q.pop();
 
        for(int i=0; i<4; i++) {
            int nx=x+dx[i];
            int ny=y+dy[i];
 
            if(nx>=0 && ny>=0 && nx<&& ny<&& !map[nx][ny])
            {
                map[nx][ny]=1;
                q.push(make_pair(nx,ny));
                cnt++;
            }
        }
    }
    section++;
    ret.push_back(cnt);
}
 
int main(void) {
    init();
 
    for(int i=0; i<n; i++) {
        for(int j=0; j<m; j++) {
            if(!map[i][j]) {
                bfs(i,j);
            }
        }
    }
 
    printf("%d\n", section);
    sort(ret.begin(), ret.end());
 
    for(int i=0; i<section; i++)
        print("%d ", ret[i]);
    return 0;
}
cs


반응형
반응형

어떤 문자가 추가되어야 하는지가 아닌 단순 몇글자가 추가되어야 하는지를 반환하기 때문에 난이도는 낮다. 혹시라도 어려움을 느낀다면 배열을 그리고 직접 손으로 따라가보면서 하는 것도 좋은 방법이다.


#include <iostream>

#include <string>

#include <algorithm>


using namespace std;

/*

* 회문 알고리즘

* 임의의 문자열s로 회문을 만든다.

* 문자열 s뒤에 0개 이상의 숫자를 추가해 회문을 생성하려고 한다.

* 가장 짧은 회문의 길이를 return

*/

int find(string s)

{

cout<<s.size()<<endl;

for(int i=s.size(); ; i++)

{

bool breakFlag=true;

for(int j=0; j<s.size(); j++)

{

if((i-j-1) < s.size() && s[j] != s[i-j-1])

{

breakFlag=false;

break;

}

}

if(breakFlag)

return i;

}

}


int main(void)

{

cout<<find("abab")<<endl;

return 0;


반응형

'Algorithm' 카테고리의 다른 글

[BOJ 2606] 바이러스  (0) 2018.12.28
[BOJ 2583] 영역구하기  (0) 2018.12.28
[TopCoder 전체탐색] 암호(Cryptography)  (0) 2018.12.20
[TopCoder 시뮬레이션] 키위주스(KiwiJuiceEasy)  (0) 2018.12.19
[BOJ 2839] 설탕배달  (0) 2018.12.18
반응형

전체탐색으로도 풀수 있지만 수학적인 내용을 가미하면 더 쉽고 효율적인 코드가 된다. 

이 문제는 전체탐색으로 풀었지만 수학적인 내용을 알게 된 문제이다.

즉 가장 작은값에 1이 증가하면 곱의 증가율이(n+1)/n이기 때문에 큰 값이 나오게 된다. n이 작으면 작을수록 값이 커지기 때문이다. 전체탐색 소스는 너무 쉽고 제약사항이 없으면 불가능하기 때문에 수학적 내용이 담긴 소스를 기재한다.


#include <stdio.h>

#include <iostream>

#include <vector>

#include <algorithm>


using namespace std;


long long encrypt(vector<int> numbers)

{

long long ret=1;

sort(numbers.begin(), numbers.end());

numbers[0]++;


for(int i=0; i<numbers.size(); i++)

{

ret*=numbers[i];

}


return ret;

}

int main(void)

{

vector<int> numbers;

for(int i=1;i<4;i++)

numbers.push_back(i);


cout<<encrypt(numbers)<<endl;

}


반응형

'Algorithm' 카테고리의 다른 글

[BOJ 2583] 영역구하기  (0) 2018.12.28
[TopCoder 전체탐색] 회문(Palindrome)  (0) 2018.12.20
[TopCoder 시뮬레이션] 키위주스(KiwiJuiceEasy)  (0) 2018.12.19
[BOJ 2839] 설탕배달  (0) 2018.12.18
[BOJ 5543] 상근날드  (0) 2018.12.18
반응형

TopCoder알고리즘 트레이닝에 수록된 문제이다.


문제

타로는 맛있는 키위 주스를 준비했습니다 타로는 0 부터 N-1이라 이름을 붙인 N개의 병에 키위주스를 넣었습니다. 
이때 i번째 병의 용량은 capacities[i]리터이며 타로가 i번째 병에 넣은 키위 주스의 양을 bottles[i]리터라고 합니다.
타로는 병에 키위주스를 재분배하려고하며 0부터 M-1까지 M회조작합니다. 
i번째 조작은 타로가 병 fromId[i]부터 toId[i]에 키위 주스를 넣는 것을 의미합니다.
병 fromId[i]가 비어 있거나 병 toId[i]가 꽉 차 있는 순간 타로는 더 이상 키위 주스를 넣지 않습니다.
N개의 요소를 가진 정수 배열 Int[]를 리턴해주세요. 
배열의 i번째 요소는 모든 주스를 쏟는 작업이 완료되고 i번째 병에 남아 있는 키위주스의 양입니다. 


제약조건: 매개변수 
 *         1. capacities :  2~50개의 요소가 있는 배열입니다. 각 요소는 1~1000000 사이의 값을 갖습니다.
 *         2. bottles : capacities 와 같은 수의 요소가 있는 배열입니다. 
 *                      bottles[i]는 capacities[i]에 들어있는 주스를 의미합니다.
 *         3. formId : 1~50 개의 요소가 있는 배열입니다.
 *         4. todoId : fromId와 같은 수의 요소가 있는 배열입니다.
 *         단, fromId, toId는 0~ (N-1)사이의 값입니다. 이때 N은 변수 capacities의 항목 개수입니다. 
 *            변수 fromId[i]와 toId[i]는 서로 다른 값을 같습니다.

함수 정의

c++

vector<int> thePouring(vector<int> capacities, vector<int> bottles, vector<int> fromId, vector<int> toId)


//

//  main.cpp

//  KiwiJuice

//

//  Created by sw on 19/12/2018.

//  Copyright © 2018 sw. All rights reserved.

//

#include <stdio.h>

#include <iostream>

#include <vector>

#include <algorithm>

using namespace std;


vector<int> thePouring(vector<int> capacities, vector<int> bottles, vector<int> fromId, vector<int> toId)

{

    for(int i=0; i<fromId.size(); i++)

    {

        int sum=bottles[fromId[i]] + bottles[toId[i]];

        bottles[toId[i]]=min(sum, capacities[toId[i]]);

        bottles[fromId[i]]=sum-bottles[toId[i]];

    }

    

    return bottles;

}


int main(int argc, const char * argv[]) {

    vector<int> capacities = {30,20,10};

    vector<int> bottles = {10,5,5};

    vector<int> fromId = {0,1,2};

    vector<int> toId = {1,2,0};

    

    vector<int> rst=thePouring(capacities, bottles, fromId, toId);

    

    for(int value:rst){

        cout<<value<<endl;

    }


    return 0;

} 


반응형
반응형

문제 출처

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


목적 : N kg 배달

제한사항 : 설탕 = 3kg, 5kg으로 구분

   설탕 N의 범위 (3<=N<=5000)

요구사항 : 최대한 적은 봉지를 출력

Ex) 18kg인 경우 5kg 3개 3kg 1개 총 4봉지만 배달하면 된다.


idea1 - Greed Algorithm을 이용

  => 항상 최적은 아님

  => 예외상황 존재

idea2 - N을 5로 나눈 몫을 5kg의 갯수 나머지를 3kg으로 나눈 몫을 3kg의 갯수로 정한다. 

    나머지가 생길경우 -1 return

  => 예외 상황 존재(input이 11인경우 output이 3이 나와야 하나 -1 나옴)


idea3 - 어쨋든 N은 3과 5로만 이루어져야하는 수!!!

  => 5가 최대가 되어야 봉지수가 최대한 적게 나온다!!

  => 이후 3으로 나눈 나머지가 0이면 답!


idea2에서 개선한 idea3 방법이 정답이였다. 이때 출력초과를 얻은 결과가 있는데 이와 같은 경우 값을 찾았음에도 불구하고 반복문을 돌기 때문에 모든 결과값을 출력하는 것을 알 수 있다 따라서 가장 먼저 값을 찾으면 루프를 빠져나올 수 있도록 개선하였다. 많은 실패가 따른 문제다..ㅠㅠ 아직도 실력부족...



#include <iostream>

#include <stdlib.h>

#define BIG_BAG 5

#define SMALL_BAG 3


using namespace std;


int sol(int& n)

{

int quotient = n/BIG_BAG;

while(quotient>=0)

{

int tmp = n - (BIG_BAG*quotient);

if(tmp % SMALL_BAG == 0)

return quotient + (tmp/SMALL_BAG);


quotient--;

}

return -1;

}

int main(void)

{

int n; //input value(sugar's kg)

cin>>n;

if(n<3 || n>5000)

exit(-1);


cout<<sol(n)<<endl;


return 0;

}



반응형
반응형

문제 출처

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


따로 풀이가 필요없는 소스

더 좋은 풀이가 있을듯 한데 궁금하다...


#include <stdio.h>

#include <iostream>

#include <algorithm>


#define MAX_COST 9999999

using namespace std;


int main(void)

{

int cost;

int minBurger=MAX_COST, minDrink=MAX_COST;

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

{

cin>>cost;

if(i<3)

minBurger=min(minBurger, cost);

else

minDrink =min(minDrink, cost);

}

cout<<minBurger + minDrink - 50<<endl;

return 0;


반응형
반응형

문제

https://www.welcomekakao.com/learn/courses/30/lessons/42893#



점수 계산식은 간단하나 풀이 중 혼동이 올 수 있으니 미리 정리해 두는 것이 좋습니다. 이 문제는 점수 계산 보다는 <meta>태그와 <a>태그를 찾아내는 것과 대문자, 소문자 구분없이 검색어가 몇번 처리됬는지 찾아내는 것이 중요합니다. 구현은 자바로 진행했습니다.



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
 
import java.util.HashMap;
import java.util.HashSet;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Solution {
    private static final Pattern URL_PATTERN = Pattern.compile("<meta property=\"og:url\" content=\"https://(.+?)\"/>");
    private static final Pattern EXTERNAL_LINK = Pattern.compile("<a href=\"https://(.+?)\">");
    private HashMap<String, Page> pageMap = new HashMap<>();
 
    private class Page {
        private HashSet<String> hadExternalLinks = new HashSet<>();
        private HashSet<String> externalLinks = new HashSet<>();
        private String html;
        private String word;
        private String url;
        private int defaultScore = 0;
        public int id;
 
        public Page(String word, String html, int id) {
            this.word = word;
            this.html = html;
            this.id = id;
            initUrl();
            initDefaultScore();
        }
 
        private void initDefaultScore() {
            int find = html.indexOf(word);
            while (find != -1)
            {
                Character[] wordBorder = { html.charAt(find - 1), html.charAt(find + word.length()) };
                if (Arrays.stream(wordBorder).anyMatch(ch -> ch.charValue() >= 'a' && ch.charValue() <= 'z'== false)
                    defaultScore++;
                find = html.indexOf(word, find + 1);
            }
        }
 
        private void initUrl() {
            Matcher matcher = URL_PATTERN.matcher(html);
            while (matcher.find())
                url = matcher.group(1);
        }
 
        public double getTotalScore() {
            double ret = defaultScore;
            for (String link : externalLinks) {
                if (pageMap.containsKey(link)) {
                    Page externalPage = pageMap.get(link);
                    if (externalPage.hadExternalLinks.size() > 0)
                        ret += (double) externalPage.defaultScore / externalPage.hadExternalLinks.size();
                }
            }
            return ret;
        }
 
        public void initExternalLink() {
            Matcher matcher = EXTERNAL_LINK.matcher(html);
            while (matcher.find()) {
                String link = matcher.group(1);
                if (hadExternalLinks.contains(link) == false)
                    hadExternalLinks.add(link);
                if (pageMap.containsKey(link))
                    pageMap.get(link).externalLinks.add(url);
            }
        }
    }
 
    public int solution(String word, String[] pages) {
        int id = 0;
        for (String html : pages) {
            Page page = new Page(word.toLowerCase(), html.toLowerCase(), id);
            pageMap.put(page.url, page);
            id++;
        }
        for (Page page : pageMap.values()) {
            page.initExternalLink();
        }
        return pageMap.values().stream().max((a, b) -> Double.compare(a.getTotalScore(), b.getTotalScore())).get().id;
    }
}
cs


반응형

'Algorithm' 카테고리의 다른 글

[BOJ 2839] 설탕배달  (0) 2018.12.18
[BOJ 5543] 상근날드  (0) 2018.12.18
[프로그래머스] K번째 수  (0) 2018.11.14
[BOJ 2293] 동전 1  (0) 2018.11.12
[BOJ 2309] 일곱 난쟁이  (0) 2018.11.12
반응형

문제

https://programmers.co.kr/learn/courses/30/lessons/42748


#include <string>

#include <vector>

#include <algorithm>


using namespace std;


vector<int> solution(vector<int> array, vector<vector<int>> commands) {

    vector<int> answer;

    int s, e, t, ret;    //시작, 끝, 타겟, 결과값

    for(int i=0; i<commands.size(); i++) {

        vector<int> tmp;

        // index값이므로 -1씩 해줌

        s=commands[i][0]-1;

        e=commands[i][1]-1;

        t=commands[i][2]-1;

        for(int j=s; j<=e; j++) {

            tmp.push_back(array[j]);

        }

        sort(tmp.begin(), tmp.end());

        ret=tmp[t];

        answer.push_back(ret);

    }

    return answer;

}



반응형

'Algorithm' 카테고리의 다른 글

[BOJ 5543] 상근날드  (0) 2018.12.18
[카카오 2019 신입공채 1차 코딩테스트] 6.매칭 점수  (0) 2018.11.14
[BOJ 2293] 동전 1  (0) 2018.11.12
[BOJ 2309] 일곱 난쟁이  (0) 2018.11.12
[BOJ 3053] 택시 기하학  (0) 2018.11.12
반응형

문제

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


역시 dp는 어렵다 ㅠㅠ 

개인적으로 표를 그리면서 차근차근 푸는것을 추천한다.

예제와 같이 1,2,5원 동전이 있고 10원을 만든다고 가정하면

1원 = 1

2원 = 1+1

   2

3원 = 1+1+1

   2+1

4원 = 1+1+1+1

   2+1+1

   2+2

5원 = 1+1+1+1+1

   1+1+1+2

   1+2+2

   5


이것은 풀어쓰면 dp[5]를 구하는 방법은 dp[1]+dp[2]+dp[0] 인 것을 알 수 있다.

dp[i]라고 가정하면 [i-동전]을 더해주는 방식이다. 처음에 이해가 되지 않아 표를 3번 이상 그려보면서 이해한 문제

시간이 지나면 또 까먹을 듯 하다.



#define _CRT_SECURE_NO_WARNINGS


#include <cstdio>

#include <iostream>

#include <algorithm>

#include <queue>

#include <stack>

#include <vector>

#include <functional>


#define MAX_SIZE 100

#define INF 0x7fffffff


using namespace std;


int N, K;

int coin[MAX_SIZE];

int dp[10001];


void solve()

{

dp[0] = 1;

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

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

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


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

for (int j = coin[i]; j <= K; j++) {

if (j - coin[i] >= 0)

dp[j] += dp[j - coin[i]];

}

}

printf("%d\n", dp[K]);

}


int main(void)

{

solve();

return 0;

}



반응형

'Algorithm' 카테고리의 다른 글

[카카오 2019 신입공채 1차 코딩테스트] 6.매칭 점수  (0) 2018.11.14
[프로그래머스] K번째 수  (0) 2018.11.14
[BOJ 2309] 일곱 난쟁이  (0) 2018.11.12
[BOJ 3053] 택시 기하학  (0) 2018.11.12
[BOJ 6591] 이항 쇼다운  (0) 2018.11.12

+ Recent posts