www.acmicpc.net/problem/15685

 

15685번: 드래곤 커브

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

www.acmicpc.net

 

 

[난이도] Gold4

[유형] 시뮬레이션 (삼성SW기출)

 

[풀이]

시키는대로 하자

 

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
int dy[4] = {0,-1,0,1};
int dx[4] = {1,0,-1,0};
int N;
bool map[102][102];
int main(){
    scanf("%d",&N);
    for(int dc=0;dc<N;dc++){
        int x,y,d,g;
        scanf("%d%d%d%d",&x,&y,&d,&g);
        vector<int> seq(1);

        for(int i=0;i<g;i++){
            int sz = seq.size();
            for(int j=sz-1;j>=0;j--) seq.push_back((seq[j]+1)%4);
        }
        map[y][x] = 1;
        for(int v : seq) {
            v=(v+d)%4;
            y+=dy[v];
            x+=dx[v];
            map[y][x] = 1;
        }
    }

    int ans = 0;
    for(int i=0;i<100;i++){
        for(int j=0;j<100;j++){
            if(map[i][j]&&map[i+1][j]&&map[i+1][j+1]&&map[i][j+1]) ans++;  
        }
    }
    printf("%d",ans);
}

github.com/has2/Problem-Solving/blob/master/boj-solved.ac/Gold4/15685.cpp

 

www.acmicpc.net/problem/14002

 

14002번: 가장 긴 증가하는 부분 수열 4

수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분 수열은 A = {10, 20, 10, 30, 20, 50} 이

www.acmicpc.net

 

 

[난이도] Gold4

[유형] DP (LIS)

 

[풀이]

d[i] = i번째 수로 끝나면서 가장 긴 증가하는 부분수열의 길이

prev[i] = i번째 수로 끝나면서 가장 긴 증가하는 부분수열에서 i번째 앞의수 위의 두가지를 이용해서 구한다.

#include <cstdio>
int N,a[1001],d[1001],prev[1001];
void prt(int n){
    if(n==0) return;
    prt(prev[n]);
    printf("%d ",a[n]);
}
int main(){
    scanf("%d",&N);
    for(int i=1;i<=N;i++) scanf("%d",&a[i]);
    for(int i=1;i<=N;i++){
        for(int j=0;j<i;j++){
            if(a[j]<a[i]) {
                if(d[i]<d[j]+1){
                   d[i]=d[j]+1;
                   prev[i]=j;
                }
            }
        }
    }
    int mxi=0,mxV=0;
    for(int i=1;i<=N;i++) {
        if(d[i] > mxV){
            mxi=i;
            mxV=d[i];
        }
    }
    printf("%d\n",mxV);
    prt(mxi);
}

github.com/has2/Problem-Solving/blob/master/boj-solved.ac/Gold4/14002.cpp

 

www.acmicpc.net/problem/13913

 

13913번: 숨바꼭질 4

수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일

www.acmicpc.net

 

 

[난이도] Gold4

[유형] BFS

 

[풀이]

최단 경로까지 출력해야 하므로 방문 체크를 할때 어디서 왔는지를 저장 후 답을 찾았을 때 재귀적으로 출력한다.

 

 

#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
int s,e,visit[100001];
void prt(int n){
    if(n==-2) return;
    prt(visit[n]);
    printf("%d ",n);
}
int main(){
    scanf("%d%d",&s,&e);
    memset(visit,-1,sizeof(visit));
    queue<int> q;
    visit[s] = -2;
    q.push(s);
    int cnt = 0;
    while(!q.empty()){
        
        int qsz = q.size();
        while(qsz--){
            int cur = q.front(); q.pop();
            if(cur==e){
                printf("%d\n",cnt);
                prt(cur);
                return 0;
            }

            int nxt;
            if(cur+1<=100000) {
                nxt = cur+1;
                if(visit[nxt]==-1){
                    visit[nxt]=cur;
                    q.push(nxt);
                }
            }
            if(cur-1>=0) {
                nxt = cur-1;
                if(visit[nxt]==-1){
                    visit[nxt]=cur;
                    q.push(nxt);
                }
            }
            if(cur*2<=100000) {
                nxt = cur*2;
                if(visit[nxt]==-1){
                    visit[nxt]=cur;
                    q.push(nxt);
                }
            }            
        }
        cnt++;
    }
}

 

github.com/has2/Problem-Solving/blob/master/boj-solved.ac/Gold4/13913.cpp

www.acmicpc.net/problem/1351

 

1351번: 무한 수열

첫째 줄에 3개의 정수 N, P, Q가 주어진다.

www.acmicpc.net

 

 

[난이도] Gold4

[유형] DP

 

[풀이]

dp[n] = dp[n/P]+dp[n/Q]

N 제한이 크므로 map을 이용한다.

#include <cstdio>
#include <map>
using namespace std;
using ll = long long;
ll N;
map<ll,ll> m;
int P,Q;
ll sol(ll n){
    if(n==0) return 1;
    if(m.find(n) != m.end()) return m[n];
    return m[n] = sol(n/P)+sol(n/Q);
}
int main(){
    scanf("%lld%d%d",&N,&P,&Q);
    printf("%lld",sol(N));
}

 

github.com/has2/Problem-Solving/blob/master/boj-solved.ac/Gold4/1351.cpp

www.acmicpc.net/problem/1339

 

 

[난이도] Gold4

[유형] Greedy / 완전탐색

 

[풀이]

1. Greedy

모든 문자가 1이라고 가정하고 각 문자의 자리수를 고려한 총합이 최대가 되는 문자에 9부터 차례로 할당했을 때의 합을 출력한다.

 

2. 완전탐색

k가 총 문자 종류의 수일 때 9-k+1 ~ 9 의 문자를 각 문자에 할당할 수 있는 모든 경우의 수를 고려하면 된다. 10!이므로 시간초과나지 않는다. (stoi를 사용했을 경우에 시간초과가 났음)

 

#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
using namespace std;
int N,a[27],ans,cnt;
int main(){
    scanf("%d",&N);
    for(int i=0;i<N;i++){
        string s;
        cin >> s;
        for(int j=0;j<s.size();j++){
            int sz = s.size()-j-1;
            int k = 1;
            while(sz--) k*=10;
            a[s[j]-'A'] += k;
        }
    }
    vector<int> v;
    for(int i=0;i<26;i++) if(a[i]) v.push_back(a[i]);
    sort(v.begin(),v.end());
    int j=0;
    for(int i=9-v.size()+1;i<=9;i++) ans += i*v[j++];
    cout << ans;
}


// #include <algorithm>
// #include <vector>
// #include <string>
// #include <iostream>
// #include <set>
// using namespace std;
// int N,cvt[27],ans;
// vector<string> a;
// int main(){
//     set<char> s;
//     scanf("%d",&N);
//     a.resize(N);
//     for(int i=0;i<N;i++){
//         cin >> a[i];
//         for(auto c : a[i]) s.insert(c);
//     }
//     vector<int> v;
//     for(int i=0;i<s.size();i++) v.push_back(9-i);
//     reverse(v.begin(),v.end());
//     do{ 
//         int i=0;
//         for(auto c : s) {
//             cvt[c-'A']=v[i++];
//         }
//         int sum = 0;
//         for(auto str : a){
//             int k=1;
//             for(int j=str.size()-1;j>=0;j--) {
//                 sum+=cvt[str[j]-'A']*k;
//                 k*=10;
//             }
//         }
//         ans = max(ans,sum);
//     }while(next_permutation(v.begin(),v.end()));
//     cout << ans;
// }

 

github.com/has2/Problem-Solving/blob/master/boj-solved.ac/Gold4/1339.cpp

www.acmicpc.net/problem/1199

 

1199번: 오일러 회로

첫 줄에는 정점의 수 N(1 ≤ N ≤ 1,000)이 주어진다. 그리고 다음 N개의 줄에 대해 인접행렬의 정보가 주어진다. i+1번째 줄에는 i번 정점에 대한 인접행렬이 주어진다. 두 정점 사이에 간선이 여러

www.acmicpc.net

 

 

[난이도] Gold4

[유형] 최소 스패닝 트리 (크루스칼)

 

[풀이] 크루스칼 알고리즘

 

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
struct edge{
    int a,b,cost;
};
int V,E,uf[10001];
vector<edge> eg;
bool cmp(edge& a,edge& b){
    return a.cost < b.cost;
}

int find(int a){
    if(uf[a]==a) return a;
    return uf[a] = find(uf[a]);
}

bool merge(int a,int b){
    int pa = find(a);
    int pb = find(b);
    if(pa==pb) return 0;
    uf[pa] = pb;
    return 1;
}
int main(){
    scanf("%d%d",&V,&E);
    for(int i=0;i<E;i++){
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        eg.push_back({a,b,c});
    }
    sort(eg.begin(),eg.end(),cmp);
    for(int i=1;i<=V;i++) uf[i] = i;
    int cnt = 0, ans = 0;
    for(int i=0;;i++){
        edge e = eg[i];
        if(merge(e.a,e.b)){
            ans+=e.cost;
            if(++cnt==V-1) break;
        }
    }
    printf("%d",ans);
}

github.com/has2/Problem-Solving/blob/master/boj-solved.ac/Gold4/1199.cpp

 

www.acmicpc.net/problem/11657

 

11657번: 타임머신

첫째 줄에 도시의 개수 N (1 ≤ N ≤ 500), 버스 노선의 개수 M (1 ≤ M ≤ 6,000)이 주어진다. 둘째 줄부터 M개의 줄에는 버스 노선의 정보 A, B, C (1 ≤ A, B ≤ N, -10,000 ≤ C ≤ 10,000)가 주어진다. 

www.acmicpc.net

 

 

[난이도] Gold4

[유형] Bellman-Ford

 

[풀이]

음의 가중치가 있는데 최단 경로를 구해야 하는 경우는 벨만포드 또는 플로이드 워셜 이용. 벨만포드 : V*E 플로이드 워셜 : V^3이므로 벨만포드를 이용한다. 최단 경로의 간선수는 최대 V-1개이기 때문에 V-1번 루프를 돌면서 최단 경로를 갱신해준다.

 

#include <cstdio>
#include <vector>
using namespace std;
using ll = long long;
int N,M;
vector<pair<int,ll>> adj[501];
ll dist[501],inf=1e18;
int main(){
    scanf("%d%d",&N,&M);
    for(int i=0;i<M;i++){
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        adj[a].push_back({b,c});
    }

    for(int i=1;i<=N;i++) dist[i] = inf;
    dist[1] = 0;
    bool cycle = 0;
    for(int i=0;i<N;i++){
        for(int j=1;j<=N;j++){
            for(auto& p : adj[j]){
                int nxt = p.first, cost=p.second;
                if(dist[j] != inf && dist[nxt] > dist[j]+cost){
                    dist[nxt] = dist[j]+cost;
                    if(i==N-1) cycle = 1;
                }
            }
        }
    }
    if(cycle) puts("-1");
    else{
        for(int i=2;i<=N;i++) printf("%lld\n",dist[i]==inf ? -1 : dist[i]);
    }
}

 

github.com/has2/Problem-Solving/blob/master/boj-solved.ac/Gold4/11657.cpp

www.acmicpc.net/problem/11404

 

11404번: 플로이드

첫째 줄에 도시의 개수 n이 주어지고 둘째 줄에는 버스의 개수 m이 주어진다. 그리고 셋째 줄부터 m+2줄까지 다음과 같은 버스의 정보가 주어진다. 먼저 처음에는 그 버스의 출발 도시의 번호가

www.acmicpc.net

 

 

[난이도] Gold4

[유형] 플로이드 워셜

 

[풀이] 플로이드 워셜

 

#include <cstdio>
#include <algorithm>
int N,M,dist[101][101],INF=9e8;
int main(){
    scanf("%d%d",&N,&M);
    for(int i=1;i<=N;i++) {
        for(int j=1;j<=N;j++) {
            dist[i][j] = INF;
            if(i==j) dist[i][j] = 0;
        }
    }
    
    for(int i=0;i<M;i++){
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        if(c < dist[a][b]) dist[a][b] = c;
    }

    for(int k=1;k<=N;k++){
        for(int i=1;i<=N;i++){
            for(int j=1;j<=N;j++){
                dist[i][j] = std::min(dist[i][j],dist[i][k]+dist[k][j]); 
            }
        }
    }

    for(int i=1;i<=N;i++){
        for(int j=1;j<=N;j++){
            printf("%d ",dist[i][j]==INF ? 0:dist[i][j]);
        }
        puts("");
    }
}

 

github.com/has2/Problem-Solving/blob/master/boj-solved.ac/Gold4/11404.cpp

+ Recent posts