BOJ : https://www.acmicpc.net/problem/4888

 

4888번: 문시티 건설

문제 인류의 과학 기술이 발전하여 달에도 도시를 지을 수 있게 되었다. 하지만 여전히 달에 무언가를 짓는 것은 굉장히 값비싼 비용이 필요하므로, N개의 도시가 있을 때 도시 간의 도로를 가능한 한 조금 지으려고 한다. 우리는 도로들이 크기 N인 싸이클을 형성하도록 만들려고 한다. 각 도시 쌍마다 사이를 왕복하는 도로를 건설하는 데 비용이 정해져 있다. 또한, 도시 i에서 도시 j로 가는 도로를 건설하면 추가적인 건설 없이 도시 j에서도 도시 i로 갈 수

www.acmicpc.net

 

채점 50%에서 틀렸다고 나온다.

어떤 부분이 틀렸는지 모르겠다....

나중에 반례나 설명을 듣게되면 다시풀어봐야겠다

 

작성해둔 코드

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
87
88
89
90
91
92
93
94
95
96
97
98
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#define MAX 999999999
using namespace std;
 
typedef pair<long longlong long> pii;
int N, C;
pii location[9];
long long dp[9][1 << 9];
long long cost[9][9];
int visit_fin;
 
void init() {
    visit_fin = (1 << N) - 1;
    for (int i = 0; i < N; i++)
        cin >> location[i].first >> location[i].second;
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            cin >> cost[i][j];
    //for (int i = 0; i < N; i++)
    //    for (int j = 0; j < (1 << N); j++)
    //        dp[i][j] = 0;
    memset(dp, 0sizeof(dp));
}
 
long long ccw(pii a, pii b, pii c) {
    int S = (b.first - a.first) * (c.second - a.second) - (b.second - a.second) * (c.first - a.first);
    if (S < 0return -1;
    else if (S > 0return 1;
    return 0;
}
 
long long ccw_check(pii a, pii b, pii c, pii d) {
    int ab = ccw(a, b, c) * ccw(a, b, d);
    int cd = ccw(c, d, a) * ccw(c, d, b);
    if (ab == 0 && cd == 0) {
        if (a > b) swap(a, b);
        if (c > d) swap(c, d);
        return a <= d && b >= c;
    }
    return ab <= 0 && cd <= 0;
}
 
long long TSP(int start, int visit, vector<pii> v) {
 
    vector<pii> in;
    for (int i = 0; i < v.size(); i++) in.push_back(v[i]);
    in.push_back({ location[start].first, location[start].second });
 
    if (visit == visit_fin) {
        if (cost[start][0== 0return MAX;
        else {
            in.push_back({ location[0].first, location[0].second });
            long long cnt = 0;
            for (int i = 0; i < in.size() - 3; i++) {
                pii a = in[i];
                pii b = in[i + 1];
                for (int j = i + 2; j < in.size() - 1; j++) {
                    pii c = in[j];
                    pii d = in[j + 1];
                    if (c != a && d != a)
                        cnt += ccw_check(a, b, c, d)*2;
                }
            }
            if (cnt) return cost[start][0+ ((cnt * (cnt - 1* C / 2));
            else return cost[start][0];
        }
    }
 
    long long& result = dp[start][visit];
    if (result) return dp[start][visit];
 
    long long len = MAX;
    for (int i = 1; i < N; i++) {
        if (cost[start][i] != 0 && (visit & (1 << i)) == 0)
            len = min(len, cost[start][i] + TSP(i, (visit | 1 << i), in));
    }
 
    return result = len;
}
 
int main() {
    ios::sync_with_stdio(0), cin.tie(0);
    
    for (int t = 1; ; t++) {
        cin >> N >> C;
        if (!&& !C) break;
 
        init();
 
        vector<pii> v;
        cout << t << ". " << TSP(01, v) << "\n";
    }
 
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

'algorithm > BOJ' 카테고리의 다른 글

BOJ 2042번 구간 합 구하기  (0) 2020.02.05
BOJ 3055번 탈출  (0) 2020.02.04
BOJ 17387, 17386번 선분 교차  (0) 2020.02.03
BOJ 12781번 PIZZA ALVOLOC  (0) 2020.02.02
BOJ 16991번 외판원 순회3  (0) 2020.02.02

BOJ : https://www.acmicpc.net/problem/17386

BOJ : https://www.acmicpc.net/problem/17387

 

삼각형의 면적 + 벡터의 식을 나타내는 CCW 를 이용하여 문제를 해결하였다.

 

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
#include <iostream>
#include <algorithm>
using namespace std;
 
typedef pair<long longlong long> xy;
 
long long ccw(xy a, xy b, xy c) {
    long long ans = (b.first - a.first) * (c.second - a.second) - (b.second - a.second) * (c.first - a.first);
    if (ans < 0return -1;
    else if (ans > 0return 1;
    return 0;
}
 
long long check(xy a, xy b, xy c, xy d) {
    long long ans1 = ccw(a, b, c) * ccw(a, b, d);
    long long ans2 = ccw(c, d, a) * ccw(c, d, b);
    if (ans1 == 0 && ans2 == 0) {
        if (a > b) swap(a, b);
        if (c > d) swap(c, d);
        if (a <= d && b >= c) return 1;
        else return 0;
    }
    if (ans1 <= 0 && ans2 <= 0return 1;
    else return 0;
}
 
int main() {
    xy a, b, c, d;
    cin >> a.first >> a.second >> b.first >> b.second;
    cin >> c.first >> c.second >> d.first >> d.second;
 
    printf("%lld", check(a, b, c, d));
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

'algorithm > BOJ' 카테고리의 다른 글

BOJ 3055번 탈출  (0) 2020.02.04
BOJ 4888번 문시티 건설  (0) 2020.02.03
BOJ 12781번 PIZZA ALVOLOC  (0) 2020.02.02
BOJ 16991번 외판원 순회3  (0) 2020.02.02
BOJ 2098번 외판원 순회  (0) 2020.02.02

BOJ : https://www.acmicpc.net/problem/12781

github : https://github.com/junho0956/Algorithm/blob/master/12781/12781/%EC%86%8C%EC%8A%A4.cpp

 

이 문제는 정해진 선인 볼록다각형 위에서 선분의 교차를 판단하는 문제입니다.

삼각형의 면적과 벡터를 이용한 공식을 이용한 CCW 함수를 이용하여 두 선분의 교차를 판별하면 됩니다.

 

 

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
#include <iostream>
using namespace std;
 
typedef struct {
    int x, y;
}pii;
 
int ccw(pii a, pii b, pii c) {
    int ans = (b.x - a.x) * (c.y - a.y) - (b.y - a.y)* (c.x - a.x);
    if (ans < 0return 1;
    else if (ans > 0return -1;
    else return 0;
}
 
int main() {
    ios::sync_with_stdio(0), cin.tie(0);
 
    pii a, b, c, d;
    cin >> a.x >> a.y >> b.x >> b.y >> c.x >> c.y >> d.x >> d.y;
    
    int ans = ccw(a, b, c) * ccw(a, b, d);
    if (ans < 0cout << "1";
    else cout << "0";
 
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

'algorithm > BOJ' 카테고리의 다른 글

BOJ 4888번 문시티 건설  (0) 2020.02.03
BOJ 17387, 17386번 선분 교차  (0) 2020.02.03
BOJ 16991번 외판원 순회3  (0) 2020.02.02
BOJ 2098번 외판원 순회  (0) 2020.02.02
BOJ 10971번 외판원 순회2  (0) 2020.02.02

BOJ : https://www.acmicpc.net/problem/16991

github : https://github.com/junho0956/Algorithm/blob/master/16991/16991/%EC%86%8C%EC%8A%A4.cpp

 

BOJ 외판원 순회2 https://junho0956.tistory.com/172?category=825557

위 문제를 통해 풀이한 문제입니다.

 

달라진 것은 소수점 표현인데,

정점이 좌표로 주어지는 방식이고, 좌표끼리의 거리를 알기 위해서

완전탐색을 통해 각 좌표사이의 거리만 구해준 후 TSP의 흐름과 똑같이 풀어주시면 됩니다

 

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
#include <cstdio>
#include <algorithm>
#include <math.h>
using namespace std;
#pragma warning(disable:4996)
#define MAX 99999999.999999
 
pair<int,int> arr[16];
double cost[16][16];
double dp[16][1 << 16];
int N;
 
double TSP(int start, int visit) {
    if (visit == ((1 << N) - 1)) {
        if (cost[start][0== 0return MAX;
        else return cost[start][0];
    }
 
    double& result = dp[start][visit];
    if (result) return result;
 
    double len = MAX;
    for (int i = 1; i < N; i++) {
        if (cost[start][i] != 0 && (visit & (1 << i)) == 0) {
            len = min(len, cost[start][i] + TSP(i, visit | (1 << i)));
        }
    }
 
    return result = len;
}
 
int main() {
    scanf("%d"&N);
 
    for (int i = 0; i < N; i++scanf("%d%d"&arr[i].first, &arr[i].second);
 
    for (int i = 0; i < N; i++) {
        int fx = arr[i].first, fy = arr[i].second;
        for (int k = i + 1; k < N; k++) {
            int lx = arr[k].first, ly = arr[k].second;
            cost[i][k] = cost[k][i] = sqrt(pow(lx - fx, 2+ pow(ly - fy, 2));
        }
    }
 
    printf("%.9f", TSP(01));
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

'algorithm > BOJ' 카테고리의 다른 글

BOJ 17387, 17386번 선분 교차  (0) 2020.02.03
BOJ 12781번 PIZZA ALVOLOC  (0) 2020.02.02
BOJ 2098번 외판원 순회  (0) 2020.02.02
BOJ 10971번 외판원 순회2  (0) 2020.02.02
BOJ 12813번 이진수 연산  (0) 2020.02.02

+ Recent posts