[문제 링크]


이전 Coder's high 제출 문제다.


어려운 문제는 아니고 그냥 조건만 맞추면 되는 문제인데, 자꾸 조건을 중간에 빼먹어서 문제였다.


처음엔 그냥 월별, 요일별로 조건문에 때려넣어서 했는데 코드가 너무 안예뻐서... 그냥 다 상수처리해서 정리하였다.


#include <iostream>
#include <string>
using namespace std;
int testcase;
const int monthEnd[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
const int monthBefore[12] = {31,31,28,31,30,31,30,31,31,30,31,30};
const string dowArr[7]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
int main(){
    cin>>testcase;
    while(testcase--){
        int cur,m,d,dowIdx;
        string dow;
        cin>>m>>d>>dow;
        for(int i = 0;i<7;i++){
            if(!dow.compare(dowArr[i])){
                dowIdx = i;
                break;
            }
        }   
        for(int i = 0; i < 7; i++){
            cur = d-(dowIdx-i);
            cur = cur<1?monthBefore[m-1] + cur : (cur>monthEnd[m-1]?cur-monthEnd[m-1]:cur);
            printf("%d ",cur);
        }
        printf("\n");
    }
} 


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

백준 - 2800 괄호 제거  (1) 2016.05.18
백준 - 11583 인경호의 징검다리  (0) 2016.05.12
백준 - 10219 Meats On The Grill  (0) 2016.05.09
더블릿 - 미로찾기/starship_maze  (0) 2016.05.09
백준 - 4781 사탕가게  (0) 2016.05.06

[문제 링크]


예전 Coder's high 제출 문제라고 한다. 처음에 기하 문제인 줄 알고 머리를 싸맸지만 알고보니 정말 간단한 문제였다.


각 고기 별로만 뒤집을 생각만 하고 있었는데.


그냥 고기판 전체를 뒤집으면 모든 고기가 뒤집힌다. (약간 낚시성 문제인거같다.. 예제 출력부터가... 물론 조건에 모든 경우는 다 가능하다고 설명하긴 했다만...)




#include <cstdio>
int testcase,H,W;
char Grill[11][11],output[11][11];
int main(){
    scanf("%d",&testcase);
    while(testcase--){
        scanf("%d %d",&H,&W);
        for(int height = 0; height<H; height++){
            getchar();
            for(int width = 0; width < W; width++){
                scanf("%c",&Grill[height][width]);
            }
            for(int width = W-1; width>=0; width--){
                printf("%c",Grill[height][width]);
            }
            printf("\n");
        }
    }
    
}


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

백준 - 11583 인경호의 징검다리  (0) 2016.05.12
알고스팟 - WEEKLYCALENDAR  (0) 2016.05.09
더블릿 - 미로찾기/starship_maze  (0) 2016.05.09
백준 - 4781 사탕가게  (0) 2016.05.06
백준 - 1238 파티  (0) 2016.04.22

[문제 링크]



DFS 문제다. 각 방이 노드, 문이 간선인 무방향 그래프로 보고 DFS로 방문하며 출력을 하면 된다.

나는 인접리스트로 문제를 풀었는데,(인접배열로 하기엔 배열의 크기가 너무 크다.)

가장 낮은 번호의 방을 먼저 방문한다고 했으므로, 인접리스트를 정렬 한 뒤에 탐색을 진행하도록 하였다.

밑은 이를 구현한 코드이다.


#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
int n,m;
vector<vector<int> > graph;
vector<int> visited;
void dfs(int cur){
    printf("%d ",cur);
    sort(graph[cur-1].begin(),graph[cur-1].end());
    for(int i =0; i<graph[cur-1].size();i++){
        if(visited[graph[cur-1][i]-1]==0){
            visited[graph[cur-1][i]-1] = 1;
            dfs(graph[cur-1][i]);
        }
    }
}
int main(){
    scanf("%d %d",&n,&m);
    graph.resize(n);
    visited.resize(n);
    for(int i = 0; i < m; i++){
        int a,b;
        scanf("%d %d",&a,&b);
        graph[a-1].push_back(b);
        graph[b-1].push_back(a);
    }
    visited[0] = 1;
    dfs(1); 
}


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

알고스팟 - WEEKLYCALENDAR  (0) 2016.05.09
백준 - 10219 Meats On The Grill  (0) 2016.05.09
백준 - 4781 사탕가게  (0) 2016.05.06
백준 - 1238 파티  (0) 2016.04.22
백준 - 1753 최단경로  (1) 2016.04.22

[문제 링크]



DP 문제이다. DP와 그리디 문제 예시로 유명한 '배낭 채우기'문제와 정말 유사한 문제이다.


배낭 채우기 문제와는 다른점은 메모이제이션 할 값이 실수형이라는 점인데, 여기서 소수 둘째자리까지만이라는 제한을 주었으므로,


이는 100을 곱해 자연수로 만든 후 처리가 가능하다.


다만 실수 자료형 부동소수점 문제로 오차가 있을 수 있으니 100을 곱한뒤 소수 첫째 자리에서 반올림해주어야 한다.


그렇게 변형한 금액으로 메모이제이션해 최대 값을 구하면 된다.


밑은 이를 구현한 코드이다.



#include <cstdio>
#include <algorithm>
#include <utility>
#include <cstring>
using namespace std;
int n, c, cache[10001];
double m, p;
typedef pair<int, int> Candy;
Candy cd[5001];
int candyStore(int money) {
    int& ret = cache[money];
    if (ret != -1) return ret;
    ret = 0;
    for (int i = 0; i <n; i++) {
        //남은 금액이 0 이상일 경우에만 비교. 
        if (money - cd[i].second >= 0) {
            int tmp = cd[i].first + candyStore(money - cd[i].second);
            ret = max(ret, tmp);
        }
    }
    return ret;
}
int main() {
    while (true) {
        memset(cache, -1, sizeof(cache));
        scanf("%d %lf", &n, &m);
        if (n == 0 && m == 0) break;
        for (int i = 0; i < n; i++) {
            scanf("%d %lf", &c, &p);
            cd[i] = make_pair(c, (int)(p*100+0.5));
        }
        printf("%d\n", candyStore((int)(m*100+0.5)));
    }
}


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

백준 - 10219 Meats On The Grill  (0) 2016.05.09
더블릿 - 미로찾기/starship_maze  (0) 2016.05.09
백준 - 1238 파티  (0) 2016.04.22
백준 - 1753 최단경로  (1) 2016.04.22
백준 - 9252 LCS 2  (0) 2016.04.17


[문제 링크]


각 도시에서 한 도시로의 왕복 최단 거리 중에 최장 거리를 구하는 문제이다(?)


directed graph이기 때문에 X라는 도시에 갈 때와, X라는 도시에서 돌아 올 때의 경로는 둘 다 다르다.


난 이 문제를 3가지 방법으로 풀었다. 

.


1. 플로이드-와샬 알고리즘으로 전체 최단 경로를 구해 푸는 방법.

플로이드-와샬 알고리즘으로는 코드도 정말 간단하고,정답도 잘 나왔지만, 플로이드-와샬 자체가 O(n^3)인 알고리즘인지라 시간초과가 났다. 가지치기를 잘 하면 accept 되는거 같긴 한데, 그래도 다익스트라를 이용하는 것 보다는 느릴거란 생각이 들었다.(또 아무래도 정점의 갯수에 비헤 간선이 워낙 적기 때문이기도 한거같다.)


2. 다익스트라 알고리즘으로 X에서 출발하는 모든 최단 경로를 구한 뒤, 각 정점별로의 최단거리 또한 구해서 X까지 가는 방법.

모든 정점에 대해서 다익스트라 알고리즘을 사용해서 최대값을 구했다. 이건 accept가 뜨긴 떴다. 하지만 개인적으로 만족스럽지 않았다. 실행 속도도 속도지만, 굳이 각 정점에 대해서 최단 거리를 구할 필요가 있나 생각이 들었다. 


3. 다익스트라 알고리즘으로 X에서 출발하는 모든 최단 경로를 구한 뒤, 모든 간선을 뒤집어서 X에서 출발하는 정점을 구하는 방법.

일단 정방향으로 되어있는 인접리스트로 최단 경로를 구하고, 그다음 역방향으로 되어있는 인접리스트로 최단 경로를 구했다. 

그냥 간선만 방향을 바꿔주면 다른 모든 정점에서 X로 오는 정점을 구하는 것과 다를 게 없다. 따라서 2번과는 다르게 다익스트라 알고리즘을 단 2번만 사용해서 최대값을 구할 수 있다.




1. 플로이드-와샬 알고리즘으로 구현한 코드

#include <cstdio>
#include <vector>
#include <algorithm>
#include <utility>
#define MAX 987654321
using namespace std;
int n, m, x;
vector<vector<int> > fw;
int main() {
    scanf("%d %d %d", &n, &m, &x);
    fw.resize(n + 1);
    for (int i = 0; i<n; i++) {
        for (int j = 0; j<n; j++) {
            fw[i].push_back(MAX);
            if (i == j) fw[i][j] = 0;
        }
    }
    for (int i = 0; i<m; i++) {
        int u, v, w;
        scanf("%d %d %d", &u, &v, &w);
        fw[u - 1][v - 1] = w;
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j<n; j++) {
            for (int k = 0; k<n; k++) {
                if (fw[k][j] > fw[k][i] + fw[i][j])
                    fw[k][j] = fw[k][i] + fw[i][j];
            }
        }
    }
    int ret = 0;
    for (int i = 0; i<n; i++)
        ret = max(ret, fw[i][x] + fw[x][i]);
    printf("%d", ret);
}



2. 다익스트라 알고리즘 N번으로 구현한 코드

#include <cstdio>
#include <queue>
#include <vector>
#include <utility>
#include <algorithm>
#define MAX 987654321
using namespace std;
vector<vector<pair<int, int> > > adj;
int n, m, x;
typedef pair<int, int> node;
struct cmp {
    bool operator()(node x, node y) {
        return x.second > y.second;
    }
};
int ret[1001] = {0,};
void dijkstra(int x,int y) {
    priority_queue<node, vector<node>, cmp> pq;
    vector<int> dist(n+1,MAX); dist[x] = 0;
    pq.push(make_pair(x,0));
    for(int i=0; i<n;i++){
        if(i!=x) pq.push(make_pair(i,MAX));
    }
    while(!pq.empty()){
        int u = pq.top().first;
        int d = pq.top().second; pq.pop();
        if(d > dist[u]) continue;
        for(int i = 0; i<adj[u].size(); i++){
            int v = adj[u][i].first;
            int w = adj[u][i].second;
            if(dist[v] > dist[u] + w){
                dist[v] = dist[u] + w;
                pq.push(make_pair(v,dist[v]));
            }
        }       
    } 
    if(y==x){
        for(int i = 0; i<n; i++) ret[i] = dist[i];
    }
    else{
        ret[x] += dist[y];
    }    
}
int main() {
    scanf("%d %d %d", &n, &m, &x);
    adj.resize(n + 1);
    for (int i = 0; i<m; i++) {
        int u, v, w;
        scanf("%d %d %d", &u, &v, &w);
        adj[u-1].push_back(make_pair(v-1, w));
    }
    dijkstra(x-1,x-1);
    for(int i=0; i<n; i++){
        if(i!=x)
            dijkstra(i,x);
    }
    int mv = 0;
    for(int i=0; i<n;i++) mv = max(mv,ret[i]);   
    printf("%d",mv);
}



3. 다익스트라 알고리즘 2번으로 구현한 코드

#include <cstdio>
#include <queue>
#include <vector>
#include <utility>
#include <algorithm>
#define MAX 987654321
using namespace std;
vector<vector<pair<int, int> > > adj1, adj2;
int n, m, x;
typedef pair<int, int> node;
struct cmp {
    bool operator()(node x, node y) {
        return x.second > y.second;
    }
};
int ret[1001] = {0,};
void dijkstra(int x, vector<vector<pair<int,int> > > adj) {
    priority_queue<node, vector<node>, cmp> pq;
    vector<int> dist(n+1,MAX); dist[x] = 0;
    pq.push(make_pair(x,0));
    for(int i=0; i<n;i++){
        if(i!=x) pq.push(make_pair(i,MAX));
    }
    while(!pq.empty()){
        int u = pq.top().first;
        int d = pq.top().second; pq.pop();
        if(d > dist[u]) continue;
        for(int i = 0; i<adj[u].size(); i++){
            int v = adj[u][i].first;
            int w = adj[u][i].second;
            if(dist[v] > dist[u] + w){
                dist[v] = dist[u] + w;
                pq.push(make_pair(v,dist[v]));
            }
        }       
    } 
    for(int i = 0; i<n; i++) ret[i] += dist[i];  
}
int main() {
    scanf("%d %d %d", &n, &m, &x);
    adj1.resize(n + 1);
    adj2.resize(n + 1);
    for (int i = 0; i<m; i++) {
        int u, v, w;
        scanf("%d %d %d", &u, &v, &w);
        adj1[u-1].push_back(make_pair(v-1, w));
        adj2[v-1].push_back(make_pair(u-1, w));
    }
    dijkstra(x-1,adj1);
    dijkstra(x-1,adj2);
    int mv = 0;
    for(int i=0; i<n;i++) mv = max(mv,ret[i]);   
    printf("%d",mv);
}


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

더블릿 - 미로찾기/starship_maze  (0) 2016.05.09
백준 - 4781 사탕가게  (0) 2016.05.06
백준 - 1753 최단경로  (1) 2016.04.22
백준 - 9252 LCS 2  (0) 2016.04.17
백준 - 9251 LCS  (0) 2016.04.17


[문제 링크]



다익스트라 알고리즘을 사용하면 된다.


다익스트라 알고리즘에 대한 설명은 다음 포스트를 참조하자


http://hsp1116.tistory.com/42



#include <cstdio>
#include <queue>
#include <vector>
#include <utility>
#define MAX 987654321
using namespace std;
vector<vector<pair<int, int> > > adj;
int n, m, x;
typedef pair<int, int> node;
struct cmp {
    bool operator()(node x, node y) {
        return x.second > y.second;
    }
};
void dijkstra(int x) {
    priority_queue<node, vector<node>, cmp> pq;
    vector<int> dist(n+1,MAX); dist[x] = 0;
    pq.push(make_pair(x,0));
    for(int i=1; i<=n;i++){
        if(i!=x) pq.push(make_pair(i,MAX));
    }
    while(!pq.empty()){
        int u = pq.top().first;
        int d = pq.top().second; pq.pop();
        if(d > dist[u]) continue;
        for(int i = 0; i<adj[u].size(); i++){
            int v = adj[u][i].first;
            int w = adj[u][i].second;
            if(dist[v] > dist[u] + w){
                dist[v] = dist[u] + w;
                pq.push(make_pair(v,dist[v]));
            }
        }       
    }
    for(int i = 1; i<=n; i++){
        printf(dist[i] == MAX? "INF\n": "%d\n",dist[i]);
    }
    
}
int main() {
    scanf("%d %d %d", &n, &m, &x);
    adj.resize(n + 1);
    for (int i = 0; i<m; i++) {
        int u, v, w;
        scanf("%d %d %d", &u, &v, &w);
        adj[u].push_back(make_pair(v, w));
    }
    dijkstra(x);
}

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

백준 - 4781 사탕가게  (0) 2016.05.06
백준 - 1238 파티  (0) 2016.04.22
백준 - 9252 LCS 2  (0) 2016.04.17
백준 - 9251 LCS  (0) 2016.04.17
알고스팟 - KOOGLE  (0) 2016.04.14


[문제 링크]



LCS2는 다음 포스트에 있는 내용과 같다.


http://hsp1116.tistory.com/37



#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
vector<char> output;
int cache[1001][1001];
char input[1001],compare[1000];
int LCS(int m,int n){
    memset(cache,0,sizeof(cache));
    for(int i=1;i<=m;i++){
        for(int j=1; j<=n;j++){
            if(compare[i-1] == input[j-1]){
                cache[i][j] = cache[i-1][j-1] +1;
                }
            else{
                cache[i][j] = std::max(cache[i-1][j], cache[i][j-1]);
            }
        }
    }
    return cache[m][n];
}
void backTracking(int m, int n){
    if(m==0 || n ==0) return;
    if(cache[m][n] > cache[m-1][n-1] && cache[m][n] > cache[m][n-1] && cache[m][n] > cache[m-1][n]){
        output.push_back(input[n-1]);
        backTracking(m-1, n-1);
    }else if(cache[m][n] > cache[m-1][n] && cache[m][n] == cache[m][n-1]){
        backTracking(m, n-1);
    }else{
          backTracking(m-1, n);
    }
}
int main(){
    scanf("%s%s",input,compare);
    int m = strlen(compare), n = strlen(input);
    printf("%d\n",LCS(m,n));
    backTracking(m,n);
    for(int i=output.size()-1;i>=0;i--)
        printf("%c",output[i]);
}


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

백준 - 1238 파티  (0) 2016.04.22
백준 - 1753 최단경로  (1) 2016.04.22
백준 - 9251 LCS  (0) 2016.04.17
알고스팟 - KOOGLE  (0) 2016.04.14
백준 - 1725, 6549 히스토그램 / 알고스팟 - FENCE  (0) 2016.03.28


[문제 링크]



LCS는 다음 포스트에 있는 내용과 같다.


http://hsp1116.tistory.com/37




#include <cstdio>
#include <algorithm>
#include <cstring>
int cache[1001][1001];
char input[1001],compare[1000];
int LCS(){
    int n = strlen(compare), m = strlen(input);
    memset(cache,0,sizeof(cache));
    for(int i=1;i<=n;i++){
        for(int j=1; j<=m;j++){
            if(compare[i-1] == input[j-1]){
                cache[i][j] = cache[i-1][j-1] +1;
                }
            else{
                cache[i][j] = std::max(cache[i-1][j], cache[i][j-1]);
            }
        }
    }
    return cache[n][m];
}
int main(){
    scanf("%s %s",input,compare);
    printf("%d\n",LCS());
}

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

백준 - 1753 최단경로  (1) 2016.04.22
백준 - 9252 LCS 2  (0) 2016.04.17
알고스팟 - KOOGLE  (0) 2016.04.14
백준 - 1725, 6549 히스토그램 / 알고스팟 - FENCE  (0) 2016.03.28
백준 - 2493 탑  (1) 2016.03.28

+ Recent posts