1. 풀이법 : map



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
#include <string>
#include <vector>
#include <map>
using namespace std;
 
string names[100001];
string Enter = "Enter";
string Leave = "Leave";
string Change = "Change";
 
vector<string> solution(vector<string> record) {
    map<stringint> m;
    int cnt = 0;
    vector<string> answer;
    // id_cnt, action
    vector<pair<intint>> ans;
    string command, uid, name;
    for (auto s : record) {
        int idx1, idx2;
 
        for (idx1 = 0; s[idx1] != ' '++idx1);
        command = s.substr(0, idx1);
 
        for (idx2 = ++idx1; idx2 < s.length() && s[idx2] != ' '++idx2);
        uid = s.substr(idx1, idx2 - idx1);
 
        if (command == Leave) {
            ans.push_back({ m[uid], 1 });
            continue;
        }
 
        name = s.substr(idx2 + 1, s.length() - idx2 - 1);
 
        if (command == Enter) {
            if (m.count(uid)) {
                names[m[uid]] = name;
            }
            else {
                m.insert({ uid, ++cnt });
                names[cnt] = name;
            }
            ans.push_back({ m[uid], 0 });
        }
        else if (command == Change) {
            names[m[uid]] = name;
        }
    }
    string com;
    for (auto i : ans) {
        string com = names[i.first];
        if (i.second == 0) {
            com += "님이 들어왔습니다.";
        }
        else {
            com += "님이 나갔습니다.";
        }
        answer.push_back(com);
    }
    return answer;
}
cs



2. 풀이법 : 누적합

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
 
int d[505];
 
vector<int> solution(int N, vector<int> stages) {
    vector<pair<doubleint>> ans;
    for (auto i : stages) 
        d[i]++;
    for (int i = N; i >= 1--i) {
        d[i] += d[i + 1];
        ans.push_back({ -double(d[i] - d[i + 1]) / double(d[i]), i });
    }
    sort(ans.begin(), ans.end());
    vector<int> answer;
    for (auto i : ans)
        answer.push_back(i.second);
    return answer;
}
cs



3. 풀이법 : 순열 + map

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
#include <string>
#include <vector>
#include <set>
using namespace std;
 
set<string> s[1<<8];
set<string> ss[8];
bool c[8];
int answers[257], ccnt;
 
inline int ctz(int a) {
    int r = 0;
    while (!(a & 1)) a >>= 1, r++;
    return r;
}
 
int solution(vector<vector<string>> relation) {
    int answer = 0;
    int siz = relation[0].size();
    for (auto i : relation) {
        for (int j = 0; j < siz; ++j) {
            if (ss[j].count(i[j])) {
                c[j] = 1;
            }
            else {
                ss[j].insert(i[j]);
            }
        }
    }
    for (int i = 0; i < siz; ++i) answer += c[i] == 0;
    for (int cnt = 2; cnt <= siz; ++cnt) {
        // cnt 개를 뽑아서 만드는 경우를 모두 만든다
        int p = (1 << cnt) - 1;
        int maxp = 1 << siz;
        while (p < maxp) {
 
            bool f = 1;
            for (int j = 0; j < siz; ++j) {
                // 단일 항목으로 후보키가 될 수 있는게 섞여있으면 최소성 불만족
                if ((!c[j] && p&(1 << j))) {
                    f = 0;
                    break;
                }
            }
            if (f) {
                f = 1;
                for (int j = 0; j < ccnt; ++j) {
                    // 후보키중 하나를 아예 포함한다면 최소성 불만족
                    if ((answers[j] & p) == answers[j]) {
                        f = 0;
                    }
                }
                if (f) {
                    for (auto j : relation) {
                        string com = "";
                        for (int k = 0; k < siz; ++k) {
                            if (p&(1 << k))
                                com += j[k];
                        }
                        if (s[p].count(com)) {
                            f = 0;
                            break;
                        }
                        else {
                            s[p].insert(com);
                        }
                    }
                    if (f) {
                        answers[ccnt++= p;
                        answer++;
                    }
                }
            }
            int t = p | (p - 1);
            p = (t + 1| (((~t&-~t) - 1>> (ctz(p) + 1));
        }
    }
    return answer;
}
cs




4. 풀이법 : 펜윅트리


음식 양에 대해 오름차순으로 정렬한 후 하나씩 먹어가면서 현재꺼 먹었을 때 k이상이 된다면 거기선 O(n)으로 하나씩 그냥 찾는다.


O( 2e6 * log2e6)


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
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
 
pair<intint> arr[200001];
int pt[200021];
ll siz;
int ch[200021];
 
int sum(int i) {
    int ans = 0;
    while (i > 0) {
        ans += pt[i];
        i -= (i&-i);
    }
    return ans;
}
 
void update(int i, int dif) {
    while (i <= siz) {
        pt[i] += dif;
        i += (i&-i);
    }
}
 
int solution(vector<int> food_times, long long k) {
    int answer = 0;
    siz = food_times.size();
    arr[0= { 1,0 };
    for (int i = 0; i < food_times.size(); ++i) {
        arr[i + 1= { food_times[i], i + 1 };
        update(i + 11);
        ch[i + 1= 1;
    }
    sort(arr + 1, arr + food_times.size() + 1);
 
    ll cur = -1;
    for (int i = 1; i <= food_times.size(); ++i) {
        ll times = arr[i].first - arr[i - 1].first;
 
        int seg = 0;
 
        if (arr[i - 1].second < arr[i].second) {
            seg = sum(arr[i].second - 1- sum(arr[i - 1].second);
        }
        else {
            times--;
            seg = sum(siz) - sum(arr[i - 1].second)    + sum(arr[i].second - 1);
        }
        ll dif = times * (siz + 1 - i) + seg + 1;
        if (k <= cur + dif) {
            cur += sum(arr[i].second) - sum(arr[i - 1].second - 1);
            
            ll cnt = (k - cur) / (siz + 1 - i);
            cur += (siz + 1 - i)*cnt;
            int pos = arr[i].second;
            if (cur == k) {
                return pos;
            }
            else if (cur > k) {
                while (cur != k) {
                    pos--;
                    if (pos == 0) pos = siz;
                    while (!ch[pos]) {
                        pos--;
                        if (pos == 0) pos = siz;
                    }
                    cur--;
                }
            }
            else {
                while (cur != k) {
                    pos++;
                    if (pos == siz + 1) pos = 1;
                    while (!ch[pos]) {
                        pos++;
                        if (pos == siz + 1) pos = 1;
                    }
                    cur++;
                }
            }
            return pos;
        }
        update(arr[i].second, -1);
        ch[arr[i].second] = 0;
        cur += dif;
    }
    return -1;
}
cs





5. 풀이법 : 세그먼트 트리


0~100000 사이에서 제일 높은것 = 루트


그 루트의 x위치를 기준으로 왼쪽, 오른쪽 구역으로 나눠서 dfs타듯이 들어가면서


세그먼트 트리로 최대값을 찾으면 그게 l_child, r_child가 된다.


O(sum(klog(1e6/k)))인데 울프람에서 그려보니 매번 풀맵 서치한다고 했을 때 k=20일 때 O(2000)이다.


결국 세그먼트 트리 만드는데 시간이 더걸린다.


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
#include <string>
#include <vector>
#include <algorithm>
#include <memory.h>
using namespace std;
 
typedef long long ll;
typedef pair<intint> pii;
int adj[1 << 17][2];
pair<intint> arr[1 << 20];
int siz;
int xpos[1 << 17];
 
void update(int i, int val, int idx) {
    i += siz;
    arr[i].first = val;
    arr[i].second = idx;
    while (i > 1) {
        i /= 2;
        arr[i] = arr[i * 2].first < arr[i * 2 + 1].first ? arr[i * 2 + 1] : arr[i * 2];
    }
}
 
pair<intint> _max(int L, int R, int nodeNum, int nodeL, int nodeR) {
    if (R<nodeL || L>nodeR) return { -1,-1 };
    if (L <= nodeL && R >= nodeR) return arr[nodeNum];
    int mid = (nodeL + nodeR) / 2;
    pii l = _max(L, R, nodeNum * 2, nodeL, mid);
    pii r = _max(L, R, nodeNum * 2 + 1, mid + 1, nodeR);
    return l.first > r.first ? l : r;
}
 
vector<int> ans1;
vector<int> ans2;
 
// 현재 위치 rnN
void dfs(int l, int r, int rnN) {
    if (r < l) return;
    ans1.push_back(rnN);
    auto left = _max(l, xpos[rnN] - 110, siz - 1);
    if (left.first != -1) {
        adj[rnN][0= left.second;
        dfs(l, xpos[rnN] - 1, left.second);
    }
 
    auto right = _max(xpos[rnN] + 1, r, 10, siz - 1);
    if (right.first != -1) {
        adj[rnN][1= right.second;
        dfs(xpos[rnN] + 1, r, right.second);
    }
    ans2.push_back(rnN);
}
 
vector<vector<int>> solution(vector<vector<int>> nodeinfo) {
    siz = 1 << 17;
    memset(arr, -1sizeof(arr));
    for (int i = 0; i < nodeinfo.size(); ++i) {
        // x = nodeinfo[i][0]
        // y = nodeinfo[i][1]
        update(nodeinfo[i][0], nodeinfo[i][1], i + 1);
        xpos[i + 1= nodeinfo[i][0];
    }
    // first = height, second = nodeNum
    pair<intint> root = _max(010000110, siz - 1);
    dfs(0100001, root.second);
    //dfs1(root.second);
    //dfs2(root.second);
    
    vector<vector<int>> answer;
    answer.push_back(ans1);
    answer.push_back(ans2);
 
 
    return answer;
}
cs


'카카오' 카테고리의 다른 글

하반기 공채 대비 실전 모의고사 1회  (0) 2018.09.03

+ Recent posts