Problem Solving/BOJ

[BOJ] 18868, 18869 :: 멀티버스Ⅰ, 멀티버스Ⅱ

happykoa 2020. 4. 11. 14:48

문제 소개

2020.04.11 기준,  solved.ac 브론즈 1티어, 실버 1티어 문제입니다.

 

바로 이전 글인 좌표 압축을 이용하는 문제입니다.

2020/04/11 - [Problem Solving/BOJ] - [BOJ] 18870: 좌표 압축

 

문제 링크

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

 

18868번: 멀티버스 Ⅰ

M개의 우주가 있고, 각 우주에는 1부터 N까지 번호가 매겨진 행성이 N개 있다. 행성의 크기를 알고 있을때, 균등한 우주의 쌍이 몇 개인지 구해보려고 한다. 구성이 같은데 순서만 다른 우주의 쌍은 한 번만 센다. 두 우주 A와 B가 있고, 우주 A에 있는 행성의 크기는 A1, A2, ..., AN, 우주 B에 있는 행성의 크기는 B1, B2, ..., BN라고 하자. 두 우주의 행성 크기가 모든 1 ≤ i, j ≤ N에 대해서 아래와 같은 조건을 만족한

www.acmicpc.net

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

 

18869번: 멀티버스 Ⅱ

M개의 우주가 있고, 각 우주에는 1부터 N까지 번호가 매겨진 행성이 N개 있다. 행성의 크기를 알고 있을때, 균등한 우주의 쌍이 몇 개인지 구해보려고 한다. 구성이 같은데 순서만 다른 우주의 쌍은 한 번만 센다. 두 우주 A와 B가 있고, 우주 A에 있는 행성의 크기는 A1, A2, ..., AN, 우주 B에 있는 행성의 크기는 B1, B2, ..., BN라고 하자. 두 우주의 행성 크기가 모든 1 ≤ i, j ≤ N에 대해서 아래와 같은 조건을 만족한

www.acmicpc.net

 

아이디어

일단, 위에 언급했듯이 좌표 압축 글을 먼저 읽어주세요.

 

제 풀이는 조금 무식하게 접근하는 풀이입니다.

1) 좌표 압축으로 주어지는 행성의 크기들을 원하는 숫자들로 바꾼다.

2) 바뀐 숫자들이 최대 10000 안에 들어올 것이므로 5자리의 문자열로 치환하고 모두 합쳐준다.

3) 합친 문자열들을 모아놓고, 정렬한 뒤 같은 것들의 개수를 세어준다. (이때 같은 것들의 개수를 세는 과정을 O(n^2) 과정으로 처리하면 안됩니다.)

4) 같은 것들의 개수가 a라면, a*(a-1)/2(aC2, 조합계산) 으로 누적한다. 

코드(cpp)

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
int M,N;
int ar[11000];
int b[11000];
vector <string> V;
int main() {
    cin >> M >> N;
    for(int t=0; t < M; t++) {
        map <int, int> m;
        string current = "";
        int cnt = 0;
        for(int x=0; x < N; x++) {
            cin >> ar[x];
            b[x] = ar[x];
        }
        sort(b,b+N);
        m[b[0]] = cnt++;
        for(int x=1; x<N; x++) {
            if(b[x] != b[x-1]) m[b[x]] = cnt++;
        }
        for(int x=0; x<N; x++) {
            int k = m[ar[x]];
            int digit = 0;
            while(k > 0) {
                digit++;
                k/=10;
            }
            for(int y =0; y< 5-digit; y++) {
                current += "0";
            }
            k = m[ar[x]];
            while(k>0) {
                current += (char) (k%10 + 48);
                k/=10;
            }
        }
        V.push_back(current);
    }
    sort(V.begin(),V.end());

    int same_cnt = 1;
    int ans = 0;

    for(int x=1; x<V.size(); x++) {
        if(V[x] != V[x-1]) {
            ans += same_cnt * (same_cnt-1) / 2;
            same_cnt = 1;
        }
        else {
            same_cnt++;
        }
    }
    ans += same_cnt * (same_cnt - 1) / 2;

    cout<<ans;
}

 

Rmx

'Problem Solving > BOJ' 카테고리의 다른 글

[BOJ] tag: minimum enclosing circle  (0) 2020.09.13
[BOJ] 9449: Garage  (0) 2020.07.17
[BOJ] 18870: 좌표 압축  (0) 2020.04.11
[BOJ] 9372: 상근이의 여행  (3) 2020.03.30
[BOJ] 2981: 검문  (0) 2020.03.27