출처:  https://www.acmicpc.net/problem/23970


문제 설명

길이 N 인 두개의 배열 A, B 가 있고, 배열 A 를 버블정렬로 정렬하는 과정에서 배열 B 와 같은 경우가 있는지 확인하는 문제


입력

배열 크기 N 과 두 개의 크기 N 인 정수 배열  A, B

출력

정렬하는 과정에서 같은 경우가 있으면 1 , 없으면 0


입력 예

6
4 6 5 1 3 2
4 1 3 2 5 6

출력 예

1

제약조건

5 <= N <= 1e4, 1 <= a_i, b_i <= 1e9


문제 풀이

Brute force 를 적용하면 bubble sort - O(N^2) 이고, 한번 swap 을 할 때 마다 길이 N 인 두 배열을 비교한다면 추가로 O(N) 이 필요해서, 전체는 O(N^3) 이 되고, 필요시간이 길어져서, 제한시간안에 해결할 수 없다.  ( N=10000 인 경우 O(N^3) 이면 1e12 정도의 계산이 필요하고, 보통 1e9 정도의 계산이 제한시간의 경계이다.)

 

먼저 확인할 것은 주어진 배열이 서로 순서만 다른 배열인지 아니면 내부에 값들이 다른 서로 다른 배열인지 구분해야 한다. 서로 다른 배열이라면, 정렬과정에서 같은 경우가 나올 수는 없다.

 

 

다음으로 순서만 서로 다른 배열이라고 하면 제일 앞에서부터 어디까지가 같은지 비교한 위치를 기록해서 그 이후 값들의 비교를 중심으로 비교하는 과정에서 중복을 줄일 수 있다. 앞에서부터 배열 A 와 배열 B 를 비교해서 일치하는 위치를 m_end로 기억한다. 배열 A를 정렬하는 과정에서 서로 바뀌는 위치를 k 라고 할 때,  k < m_end 인 경우는 계속되는 정렬과정에서 원래 있던 값으로 돌아 갈 수 없으므로 실패가 된다. 또한 m_end < k 인 경우에는 배열 A 와 배열 B 를 비교하면서, 마지막 일치하는 위치 이후의 값들만 비교하고, 계속해서 m_end 값을 갱신해서, 추가적으로 비교해야 하는 경우를 줄 일 수 있다.

프로그램 내용

더보기
..
    if(j < m_end)
    {
        cout << 0;
        return 0;
    }

    for(int k = m_end; k<tN; ++k)
    {
        if(vals[k] == refs[k])
        {
            m_end++;
        }
        else
        {
            break;
        }
    }

    if(m_end == tN)
    {
        cout << 1;
        return 0;
    }
...
...

 

관련된 문제

 

'Baekjoon Online Judge' 카테고리의 다른 글

BOJ 2824 최대공약수  (0) 2021.12.03
BOJ 15686 - 치킨 배달  (0) 2020.03.25
BOJ 2903 - 중앙 이동 알고리즘  (0) 2020.01.28
BOJ 17404 - RGB거리 2  (0) 2019.12.10

출처: https://www.acmicpc.net/problem/2824


문제 설명

주어진 수들을 곱해서 만들어지는 큰 수 N, M 의 최대 공약수를 구하는 문제


입력

N을 만드는 곱할 수의 개수(n), 곱할 수들(n_1, ... , n_n) 열, M을 만드는 곱할 수의 개수(m), 곱할 수들 (m_1, ..., m_m)

출력

최대 공약수를 출력한다. 단, 최대 공약수가 1e9 보다 크다면 마지막 9자리만 출력한다. 


입력 예

3

2 3 5

2 5

출력 예

10

제약조건

1 <= N, M <= 1000, 1 <= n_i, m_i <= 1e9


문제 풀이

곱해서 만들어지는 큰 수를  A, B 라고 할때,  prime factorization 을 하면, A = p1^a1 x p2^a2 ... B = p1^b1 x p2^b2 ... 형태로 쓸 수 있고, 같은 소수가 있을 때 그중 거듭제곱이 낮은 것들을 골라서 모두 곱하면 최대 공약수가 된다. 이것을 위해서 곱해서 만들어지는 수들을 각각 소인수분해를 하고 그것을 map<int, int>에 저장한다. 나중에 하나를 기준으로 작은 것들을 골라서 곱하고 크기가 1e9과 비교해서 더 커지지 않는지 확인해서 출력한다. Modulo 연산은 곱셈에 닫혀 있으므로 곱하는 중간에 처리해도 결과 값은 달라지지 않는다.

프로그램 내용

더보기
for(map<int, int>::iterator it = f_n.begin(); it != f_n.end(); ++it)
    {
        int prime;
        int power;
        
        prime = it->first;
        power = min(it->second, f_m[prime]);
        
        // cout << prime << " " << power << "\n";
        
        for(int i = 0; i<power; ++i)
        {
            ans *= prime;
            
            if(ans >= MAX_F)
            {
                ans %= MAX_F;
                flag = true;
            }
        }
    }

 

관련된 문제

 

'Baekjoon Online Judge' 카테고리의 다른 글

BOJ 23970 알고리즘 수업 - 버블 정렬 3  (0) 2022.02.13
BOJ 15686 - 치킨 배달  (0) 2020.03.25
BOJ 2903 - 중앙 이동 알고리즘  (0) 2020.01.28
BOJ 17404 - RGB거리 2  (0) 2019.12.10

출처: https://www.acmicpc.net/problem/15686


문제 설명

NxN grid위에 위치한 두 점(a, b), (c, d) 사이의 거리를 r = abs(a-c) + abs(b-d)로 정의한다.  문제에서는 각 집에서 가장 가까운 치킨집까지의 거리를 그 집의 치킨거리로 하고, 모든 집의 치킨 거리의 합을 도시의 치킨 거리로 한다.

치킨집의 수를 줄이고, 이때 도시의 치킨거리 최소값을 구하는 문제이다.


입력

N M

NxN

0 - 길, 1 - 집, 2 - 치킨집

출력

도시 치킨 거리 최소값


입력 예

5 2

0 2 0 1 0

1 0 1 0 0

0 0 0 0 0

2 0 0 1 1

2 2 0 1 2

출력 예

10

제약조건

2 <= N <=50 , 1 <= M <=13


문제 풀이

N x N Grid를 읽어 들이면서 집의 위치와 치킨집의 위치를 vector<pair<int, int>> 에 저장한다.

치킨집 배열에서 M개를 고르고, 이 때 각 집들에서 치킨 거리를 구하고, 그 합을 비교해서 최소값을 찾는다.

M개를 고르기 위해서, bitset을 이용해서, 치킨집들을 선택한다. 

프로그램 내용

더보기
...
bitset<MAX_M> bsets;
int min_dist = INT_MAX;	
vector<pair<int, int>> t_shops;
	
for(int b = 0; b < (1<<(int)shops.size()); ++b)
{
	if (__builtin_popcount(b) == tM) 
    {
    	bsets = b;   /// 해당하는 치킨집 조합 결정
    	for(int id=0; id< (int)shops.size();++id)
        {
        	if(bsets[id]) 
        	{
        		t_shops.push_back(shops[id]);
	        }				
		}
        int t_dist = 0;
        for(int id = 0; id<(int)house.size(); ++id)
        {
        	int h_dist = INT_MAX;
            int ht_dist = INT_MAX;
            int x, y;
            tie(x, y) = house[id];								
            for(int idn = 0; idn < (int)t_shops.size(); ++idn)
            {
    	        int t_x, t_y;
        	    tie(t_x, t_y) = t_shops[idn];									
            	int hh_dist = abs(x - t_x) + abs(y - t_y);
            	if( ht_dist > hh_dist)
            		ht_dist = hh_dist;
			}
            if (h_dist > ht_dist)	/// 각 집의 치킨거리 최소값
            	h_dist = ht_dist;
			t_dist += h_dist;
		}
	t_shops.clear();
	if( min_dist > t_dist)	/// 도시 치킨 거리 최소값
        min_dist = t_dist;
	}
}

 

관련된 문제

  • bitset :   USACO Trainging : 2.1.6 Healthy Holsteins ( link )

 

'Baekjoon Online Judge' 카테고리의 다른 글

BOJ 23970 알고리즘 수업 - 버블 정렬 3  (0) 2022.02.13
BOJ 2824 최대공약수  (0) 2021.12.03
BOJ 2903 - 중앙 이동 알고리즘  (0) 2020.01.28
BOJ 17404 - RGB거리 2  (0) 2019.12.10

출처: https://www.acmicpc.net/problem/2903


문제 설명

4개의 점으로 만들어진 사각형에 점을 추가해서 새로운 사각형을 만드는 과정을 진행한다. 점을 추가하는 규칙은 사각형의 중앙과 각 변의 중앙에 추가한다. 이 과정을 N번 시행한후 점의 수를 출력한다.


입력

N

출력

N번의 과정이후의 점의 수


입력 예

1

출력 예

9

제약조건

1 <= N  <= 15


문제 풀이

각 과정에서 늘어나는 사각형의 수, 변의 수, 점의 수들을 단계적으로 계산한다.

- 새로운 사각형은 원래 있던 사각형*4가 된다.

- 새로운 변은 원래 있던 변의 수*2(변의 중점으로 인한 분할) + 사각형*4 (면의 중점과 각변을 연결하는 선)

- 새로운 점은 각 변의 수(새로운 중점)와 사각형의 수(중점) 만큼 추가된다.  

프로그램 내용

더보기
...
vector<int> dots(16,0);
vector<int> edges(16, 0);
vector<int> faces(16,0);
    
dots[0] = 4;
faces[0] = 1;
edges[0] = 4;
    
for(int id=1; id<=15 ; ++id)
{
	faces[id] = faces[id-1]*4;
	edges[id] = edges[id-1]*2 + faces[id-1]*4;
	dots[id] = dots[id-1] + faces[id-1] + edges[id-1];
}
...

 

관련된 문제

 

'Baekjoon Online Judge' 카테고리의 다른 글

BOJ 23970 알고리즘 수업 - 버블 정렬 3  (0) 2022.02.13
BOJ 2824 최대공약수  (0) 2021.12.03
BOJ 15686 - 치킨 배달  (0) 2020.03.25
BOJ 17404 - RGB거리 2  (0) 2019.12.10

출처: https://www.acmicpc.net/problem/17404


문제 설명

1~N개의 집 칠하는데, 옆집과는 다른 색으로 칠하는데 필요한 최소 비용. 집의 배치는 원형으로 생각해서 첫집과 마지막집이 이웃이 되도록 한다.


입력

집의 수와 각각의 집을 칠하는데 필요한 비용

출력

필요한 최소 비용 

입력 예

3
26 40 83
49 60 57
13 89 99

출력 예

110

제약조건

  • 1<= N <= 1000
  • 1 <= a_i <= 1000

문제 풀이

RGB거리 문제에서 약간의 변형이 있다. 집들의 시작과 끝이 연결되어 초기조건을 한번 정하는 것으로 결정할 수 없도록 변형됐다. 기본 아이디어는 초기조건과 거기에 따른 제한 조건을 만족하는 최소의 값들을 찾어서, 비교하도록 했다.

첫집을 특정한 색으로 칠하는 경우에 그 색을 제외한 다른 색들은 아주 큰값으로 설정해서 다음번 집 계산에서 선택되지 않도록 해서 마지막 집까지 최소값을 구한다. 마지막집을 칠하는 최소값에서 첫집과 같은 색깔로 칠하는 경우는 배제하고 최소값을 구한다.  

프로그램 내용

더보기
const int INF = 987654321;
int tN;

/// 색깔별로 칠하는 최소비용을 계산한다
int minPaint(vector<tuple<int, int, int>>& p_cost, int color);

int main()
{
    cin >> tN;

    /// 각 집을 칠하는 비용 입력
    vector<tuple<int, int, int>> p_cost(tN);
    for(int id=0; id< tN; ++id)
    {
	...
	}

    int cost_r = minPaint(p_cost, 0); // first hosuse red
    int cost_g = minPaint(p_cost, 1); // first hosuse green
    int cost_b = minPaint(p_cost, 2); // first hosuse blue

  	int cost = min({cost_r, cost_g, cost_b}); 

    cout << cost << "\n";

 

관련 문제

 

RGB 거리 (1149)  

'Baekjoon Online Judge' 카테고리의 다른 글

BOJ 23970 알고리즘 수업 - 버블 정렬 3  (0) 2022.02.13
BOJ 2824 최대공약수  (0) 2021.12.03
BOJ 15686 - 치킨 배달  (0) 2020.03.25
BOJ 2903 - 중앙 이동 알고리즘  (0) 2020.01.28

+ Recent posts