반응형

1

티어 : Silver 3
시간 제한 : 1 초
메모리 제한 : 128 MB
알고리즘 분류 : 수학, 브루트포스 알고리즘, 정수론

 

문제

2와 5로 나누어 떨어지지 않는 정수 n(1 ≤ n ≤ 10000)가 주어졌을 때, 1로만 이루어진 n의 배수를 찾는 프로그램을 작성하시오.

 

입력

입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스는 한 줄로 이루어져 있고, n이 주어진다.

 

출력

1로 이루어진 n의 배수 중 가장 작은 수의 자리수를 출력한다.

 

예제 입출력


우선 알고리즘은 각 자릿수가 1로 이루어진 숫자로 n이 나누어 떨어질 때까지 확인하는 방식을 이용했다.

처음에는 각 자릿수가 1로 이루어진 숫자를 만들기 위해 문자열을 이용했다.

num이라는 string형 변수를 하나 만들어 n으로 나누어떨어지지 않으면 '1'을 추가해주는 방식으로 아래와 같이 구현했다.

#include <iostream>
#include <string>
using namespace std;

int cal_len(long long n){
    string num = to_string(n);
    return num.length();
}

long long ispossible(int n){
    // n의 길이 계산
    int len = cal_len(n);
    string num;
    // n의 길이만큼 1로만 구성된 문자열 만들기
    for(int i=0;i<len;i++){
        num += '1'; // O(n)으로 동작
    }
 
    while(true){
        // num이 n의 배수인지 확인
        if(num%n==0) return num.length();
        // num 한 자리 추가
        num += '1';
    }
    return -1;
}

int main(void){
    int n;
    while(true){ 
        cin >> n;
        if(cin.eof()) break; // EOF이면 입력이 취소되고 true 반환
        cout << ispossible(n) << "\n";
    }
    return 0;
}

하지만 런타임 에러(out_of_range)로 실패 ㅠ

num += '1';의 연산이 O(n)으로 동작하기 때문에 연산량이 너무 많기 때문이다.

 

그래서 num 변수를 long long형으로 선언해 동일한 알고리즘을 사용했다.

#include <iostream>
using namespace std;

long long ispossible(int n){
    int cnt=1;
    long long num=1;
 
    while(true){
        // num이 n의 배수인지 확인
        if(!(num%n)) return cnt;
        
        // num 한 자리 추가
        num = num*10+1;
        cnt++;
    }
    return -1;
}

int main(void){
    int n;
    while(true){ 
        cin >> n;
        if(cin.eof()) break; // EOF이면 입력이 취소되고 true 반환
        cout << ispossible(n) << "\n";
    }
    return 0;
}

하지만 이 방법도 동일하게 런타임 에러(out_of_range)가 났다.

 

결과적으로 런타임 에러의 원인은 num이 너무 커지는 것이었는데, num을 줄이기 위해 Moduler(%) 연산을 이용했다.

Algorithm

Brute Force
1. num(long long형)에 1로 이루어진 숫자를 하나씩 담음
2. num이 n으로 나누어 떨어지는지 확인
    2-1. 나누어떨어지면 num의 길이 return
    2-2. 나누어떨어지지 않으면 num의 길이 증가 (num = num*10 + 1 연산)
            → 이 때 moduler 연산(num%=n)을 이용해 num의 크기 줄여주는 것이 이 문제의 핵심 !

 

Code

#include <iostream>
using namespace std;

long long ispossible(int n){
    int cnt=1;
    long long num=1;
 
    while(true){
        // num이 n의 배수인지 확인
        if(!(num%n)) return cnt;
        
        // num의 크기 줄여주기
        num%=n;
        
        // num 한 자리 추가
        num = num*10+1;
        cnt++;
    }
    return -1;
}

int main(void){
    int n;
    while(true){ 
        cin >> n;
        if(cin.eof()) break; // cin.eof(): EOF이면 입력이 취소되고 true 반환
        cout << ispossible(n) << "\n";
    }
    return 0;
}

메모리: 2020 KB
시간: 0 ms

반응형

'백준 > C++' 카테고리의 다른 글

[백준 1037] 약수 C++  (0) 2022.12.03
[백준 10430] 나머지 C++  (0) 2022.12.02
반응형

마인크래프트

티어 : Silver 2
시간 제한 : 1 초 (추가 시간 없음)
메모리 제한 : 1024 MB
알고리즘 분류 : 구현, 브루트포스 알고리즘

 

문제

팀 레드시프트는 대회 준비를 하다가 지루해져서 샌드박스 게임인 ‘마인크래프트’를 켰다. 마인크래프트는 1 × 1 × 1(세로, 가로, 높이) 크기의 블록들로 이루어진 3차원 세계에서 자유롭게 땅을 파거나 집을 지을 수 있는 게임이다.

목재를 충분히 모은 lvalue는 집을 짓기로 하였다. 하지만 고르지 않은 땅에는 집을 지을 수 없기 때문에 땅의 높이를 모두 동일하게 만드는 ‘땅 고르기’ 작업을 해야 한다.

lvalue는 세로 N, 가로 M 크기의 집터를 골랐다. 집터 맨 왼쪽 위의 좌표는 (0, 0)이다. 우리의 목적은 이 집터 내의 땅의 높이를 일정하게 바꾸는 것이다. 우리는 다음과 같은 두 종류의 작업을 할 수 있다.

  1. 좌표 (i, j)의 가장 위에 있는 블록을 제거하여 인벤토리에 넣는다.
  2. 인벤토리에서 블록 하나를 꺼내어 좌표 (i, j)의 가장 위에 있는 블록 위에 놓는다.

1번 작업은 2초가 걸리며, 2번 작업은 1초가 걸린다. 밤에는 무서운 몬스터들이 나오기 때문에 최대한 빨리 땅 고르기 작업을 마쳐야 한다. ‘땅 고르기’ 작업에 걸리는 최소 시간과 그 경우 땅의 높이를 출력하시오.

단, 집터 아래에 동굴 등 빈 공간은 존재하지 않으며, 집터 바깥에서 블록을 가져올 수 없다. 또한, 작업을 시작할 때 인벤토리에는 B개의 블록이 들어 있다. 땅의 높이는 256블록을 초과할 수 없으며, 음수가 될 수 없다.

 

입력

첫째 줄에 N, M, B가 주어진다. (1 ≤ M, N ≤ 500, 0 ≤ B ≤ 6.4 × 107)

둘째 줄부터 N개의 줄에 각각 M개의 정수로 땅의 높이가 주어진다. (i + 2)번째 줄의 (j + 1)번째 수는 좌표 (i, j)에서의 땅의 높이를 나타낸다. 땅의 높이는 256보다 작거나 같은 자연수 또는 0이다.

 

출력

첫째 줄에 땅을 고르는 데 걸리는 시간과 땅의 높이를 출력하시오. 답이 여러 개 있다면 그중에서 땅의 높이가 가장 높은 것을 출력하시오.

 

예제 입출력


Algorithm

구현
1. 기준 높이보다 높은 블럭의 차이 모두 합하기
2. 기준 높이보다 낮은 블럭의 차이 모두 합하기
3. 기준 높이만큼 쌓을 수 있는 블럭이 존재하면 answer 갱신

 

Code

import sys
input = sys.stdin.readline

N, M, B = map(int, input().split())
graph = [list(map(int, input().split())) for _ in range(N)]

max_height = 0
min_height = 256
for x in range(len(graph)):
    for y in graph[x]:
        max_height = max(max_height, y)
        min_height = min(min_height, y)

answer = [(256*2+256)*M*N, max_height]
height = max_height
while height >= min_height:
    # 기준 높이보다 높은 블럭의 차이 모두 합하기
    # 기준 높이보다 낮은 블럭의 차이 모두 합하기
    tall = 0
    short = 0
    for x in range(len(graph)):
        for y in range(len(graph[x])):
            if graph[x][y] > height:
                tall += (graph[x][y] - height)
            elif graph[x][y] < height:
                short += (height - graph[x][y])

    # 기준 높이만큼 쌓을 수 있는 블록이 충분히 존재하면 answer 갱신
    if (B+tall) >= short:
        if answer[0] > tall * 2 + short:
            answer = [tall * 2 + short, height]
    
    # 기준 높이를 낮춰 재검사
    height -= 1
        
print(answer[0], answer[1])

메모리: 117584 KB
시간: 900 ms

반응형
반응형

안전 영역

티어 : Silver 1
시간 제한 : 1 초
메모리 제한 : 128 MB
알고리즘 분류 : 그래프 이론, 브루트포스 알고리즘, 그래프 탐색, 너비 우선 탐색, 깊이 우선 탐색

 

문제

재난방재청에서는 많은 비가 내리는 장마철에 대비해서 다음과 같은 일을 계획하고 있다. 먼저 어떤 지역의 높이 정보를 파악한다. 그 다음에 그 지역에 많은 비가 내렸을 때 물에 잠기지 않는 안전한 영역이 최대로 몇 개가 만들어 지는 지를 조사하려고 한다. 이때, 문제를 간단하게 하기 위하여, 장마철에 내리는 비의 양에 따라 일정한 높이 이하의 모든 지점은 물에 잠긴다고 가정한다.

어떤 지역의 높이 정보는 행과 열의 크기가 각각 N인 2차원 배열 형태로 주어지며 배열의 각 원소는 해당 지점의 높이를 표시하는 자연수이다. 예를 들어, 다음은 N=5인 지역의 높이 정보이다.

6 8 2 6 2
3 2 3 4 6
6 7 3 3 2
7 2 5 3 6
8 9 5 2 7

이제 위와 같은 지역에 많은 비가 내려서 높이가 4 이하인 모든 지점이 물에 잠겼다고 하자. 이 경우에 물에 잠기는 지점을 회색으로 표시하면 다음과 같다. 

6 8 2 6 2
3 2 3 4 6
6 7 3 3 2
7 2 5 3 6
8 9 5 2 7

물에 잠기지 않는 안전한 영역이라 함은 물에 잠기지 않는 지점들이 위, 아래, 오른쪽 혹은 왼쪽으로 인접해 있으며 그 크기가 최대인 영역을 말한다. 위의 경우에서 물에 잠기지 않는 안전한 영역은 5개가 된다(꼭짓점으로만 붙어 있는 두 지점은 인접하지 않는다고 취급한다). 

또한 위와 같은 지역에서 높이가 6이하인 지점을 모두 잠기게 만드는 많은 비가 내리면 물에 잠기지 않는 안전한 영역은 아래 그림에서와 같이 네 개가 됨을 확인할 수 있다. 

6 8 2 6 2
3 2 3 4 6
6 7 3 3 2
7 2 5 3 6
8 9 5 2 7

이와 같이 장마철에 내리는 비의 양에 따라서 물에 잠기지 않는 안전한 영역의 개수는 다르게 된다. 위의 예와 같은 지역에서 내리는 비의 양에 따른 모든 경우를 다 조사해 보면 물에 잠기지 않는 안전한 영역의 개수 중에서 최대인 경우는 5임을 알 수 있다. 

어떤 지역의 높이 정보가 주어졌을 때, 장마철에 물에 잠기지 않는 안전한 영역의 최대 개수를 계산하는 프로그램을 작성하시오. 

 

입력

첫째 줄에는 어떤 지역을 나타내는 2차원 배열의 행과 열의 개수를 나타내는 수 N이 입력된다. N은 2 이상 100 이하의 정수이다. 둘째 줄부터 N개의 각 줄에는 2차원 배열의 첫 번째 행부터 N번째 행까지 순서대로 한 행씩 높이 정보가 입력된다. 각 줄에는 각 행의 첫 번째 열부터 N번째 열까지 N개의 높이 정보를 나타내는 자연수가 빈 칸을 사이에 두고 입력된다. 높이는 1이상 100 이하의 정수이다.

 

출력

첫째 줄에 장마철에 물에 잠기지 않는 안전한 영역의 최대 개수를 출력한다.

 

예제 입출력


Algorithm

DFS
1. 높이 정보 그래프 구현
2. dfs를 이용해 잠기지 않는 지역의 덩어리 구하기
3. 최댓값 출력

 

Code

import sys
sys.setrecursionlimit(10**9)
input = sys.stdin.readline

def dfs(x, y, amount_of_rain):
    
    # 위치를 벗어나면 return
    if x < 0 or x > N-1 or y < 0 or y > N-1:
        return False
    
    # 방문한 기록 있거나 높이가 비의 양보다 작거나 같으면 return
    if visited[x][y] or height_info[x][y] <= amount_of_rain:
        return False
    
    # 방문 기록
    visited[x][y] = True
    
    # 주변 노드 방문
    for dx, dy in dir:
        dfs(x+dx, y+dy, amount_of_rain)
    
    return True

N = int(input())
height_info = [list(map(int, input().split())) for _ in range(N)]

# 상, 하, 좌, 우
dir = [(-1, 0), (1, 0), (0, -1), (0, 1)]

# height_info의 최댓값 찾기
max_ = 0
for i in range(N):
    max_ = max(max_, max(height_info[i]))

answer = 0
for amount_of_rain in range(max_+1):
    count = 0 # 덩어리 개수
    visited = [[False for _ in range(N)] for _ in range(N)]
    
    # dfs 돌면서 비의 양보다 높은 곳만 접근했을 때의 덩어리 개수 구하기
    for x in range(len(height_info)):
        for y in range(len(height_info[i])):
            if dfs(x, y, amount_of_rain):
                count += 1
    answer = max(answer, count)

print(answer)

메모리: 40748 KB
시간: 1684 ms

반응형

'백준 > Python' 카테고리의 다른 글

[백준 11057] 오르막 수 Python  (0) 2022.05.31
[백준 10844] 쉬운 계단 수 Python  (0) 2022.05.31
[백준 16953] A→B Python  (0) 2022.05.30
[백준 9372] 상근이의 여행 Python  (0) 2022.05.30
[백준 1003] 피보나치 함수 Python  (0) 2022.05.30
반응형

근손실

티어 : Silver 3
시간 제한 : 1 초
메모리 제한 : 256 MB
알고리즘 분류 : 브루트포스 알고리즘, 백트래킹

 

문제

웨이트 트레이닝을 좋아하는 어떤 대학원생은, 현재 3대 운동 중량 500의 괴력을 소유하고 있다. 다만, 하루가 지날 때마다 중량이 K만큼 감소한다. 예를 들어 K=4일 때, 3일이 지나면 중량이 488로 감소하게 된다. 따라서 운동을 하지 않고, 가만히 있다면 매일매일 중량이 감소할 뿐이다.

다행히도 이 대학원생은 N개의 서로 다른 운동 키트를 가지고 있다. 이 대학원생은 하루에 1개씩의 키트를 사용하며, 매일 어떤 키트를 사용할 지는 마음대로 결정할 수 있다. 운동 키트들은 각각의 중량 증가량을 가지고 있으며, 사용할 때마다 즉시 중량이 증가하게 된다. 이 때 몇몇 운동 키트들의 중량 증가량이 같을 수 있으나, 서로 다른 운동 키트로 간주한다. 각각의 운동 키트는 N일 동안 한 번씩만 사용할 수 있다.

대학원생은 운동 기간동안 항상 중량이 500 이상으로 유지가 되도록 N일간의 운동 플랜을 세우고자 한다. 1일차부터 N일차까지의 모든 기간동안, 어떤 시점에서라도 중량이 500보다 작아지지 않도록 해야 한다.

예를 들어 N=3, K=4일 때, 각 운동 키트의 중량 증가량이 다음과 같다고 가정하자.

이 때 1번, 3번, 2번 순서대로 운동 키트를 적용한다고 해보자. 이 경우 운동 1일차에 대학원생은 중량이 3만큼 증가하지만 그와 동시에 하루에 중량이 4만큼 감소하기 때문에, 1일이 지난 이후에 중량은 499가 된다. 따라서 조건을 만족하지 못한다.

반면에 3번, 1번, 2번 순서대로 운동 키트를 적용한다고 해보자. 그러면 1일차부터 운동을 모두 마친 날까지의 모든 시점에 대하여 항상 중량이 500이상이 된다.

N개의 운동 키트에 대한 정보가 주어졌을 때, N일간 하루에 1개씩의 운동 키트를 사용하는 모든 경우 중에서, 운동 기간동안 항상 중량이 500 이상이 되도록 하는 경우의 수를 출력하는 프로그램을 작성하시오.

위 예시에서는 모든 경우 중에서 총 4가지 경우가 조건을 만족한다.

 

입력

첫째 줄에 자연수 N K가 공백을 기준으로 구분되어 주어진다. (1 ≤ ≤ 8, 1 ≤ ≤ 50) 둘째 줄에 각 운동 키트의 중량 증가량 A가 공백을 기준으로 구분되어 주어진다. (1 ≤ ≤ 50)

 

출력

N일 동안 N개의 운동 키트를 사용하는 모든 경우 중에서, 운동 기간동안 항상 중량이 500 이상이 되도록 하는 경우의 수를 출력한다.

 

예제 입출력


Algorithm

Back Tracking
1. stack에 운동 키트 추가
    ☞ stack에 들어있지 않은 숫자만 추가
2. 운동 키트 적용 직후 중량 갱신
3. 재귀함수 호출
4. 재귀함수 return되면 중량 원상복구 후 pop
5. stack의 길이가 N이 되거나 중량이 500 미만이 되면 pop먼저 할 수 있도록 구현

 

Code

def back_tracking(now_weight):
    global answer
    
    # stack의 길이가 N이 되거나 중량이 500 미만이 되면 POP먼저 하도록 구현
    if len(stack) == N or now_weight < 500:
        pass
    else:
        for idx in range(N):
            if idx not in stack:
                stack.append(idx)
                # 중량 계산
                now_weight = now_weight - K + weights[idx]
                # 마지막 index이고 중량이 500이상이면 answer 증가
                if len(stack) == N and now_weight >= 500:
                    answer += 1
                back_tracking(now_weight)
                stack.pop()
                now_weight = now_weight + K - weights[idx]

N, K = map(int, input().split())
weights = list(map(int, input().split()))
stack = []
global answer
answer = 0
now_weight = 500
back_tracking(now_weight)
print(answer)

메모리: 30840 KB
시간: 176 ms

반응형
반응형

부분수열의 합

티어 : Silver 2
시간 제한 : 2 초
메모리 제한 : 256 MB
알고리즘 분류 : 브루트포스 알고리즘, 백트래킹

 

문제

N개의 정수로 이루어진 수열이 있을 때, 크기가 양수인 부분수열 중에서 그 수열의 원소를 다 더한 값이 S가 되는 경우의 수를 구하는 프로그램을 작성하시오.

 

입력

첫째 줄에 정수의 개수를 나타내는 N과 정수 S가 주어진다. (1 ≤ N ≤ 20, |S| ≤ 1,000,000) 둘째 줄에 N개의 정수가 빈 칸을 사이에 두고 주어진다. 주어지는 정수의 절댓값은 100,000을 넘지 않는다.

 

출력

첫째 줄에 합이 S가 되는 부분수열의 개수를 출력한다.

 

예제 입출력

 


Algorithm

Back Tracking
1. stack에 수열의 숫자 하나씩 추가
1.1. stack이 비어있으면 바로 append
1.2. stack이 비어있지 않으면 stack의 마지막 숫자보다 큰 숫자만 추가
2. stack 원소의 합이 S가 되면 ANSWER 1 증가
3. 재귀함수 호출
4. 재귀함수 return되면 pop
5. stack의 길이가 N이 되면 바로 append하지 못하도록 구현

 

Code

def back_tracking(sum_):
    global answer
    
    # stack 길이가 N이 되면 POP먼저 하도록 구현
    if len(stack) == N:
        pass
    else:
        for idx in range(N):
            # stack 비어있으면 바로 append
            if not stack:
                stack.append(idx)
                sum_ += list_[idx]
                if sum_ == S:
                    answer += 1
                back_tracking(sum_)
                stack.pop()
                sum_ -= list_[idx]
                
            # stack 비어있지 않으면 들어있지 않은 숫자만 추가
            elif stack[-1] < idx:
                stack.append(idx)
                sum_ += list_[idx]
                if sum_ == S:
                    answer += 1
                back_tracking(sum_)
                stack.pop()
                sum_ -= list_[idx]
                
N, S = map(int, input().split())
list_ = list(map(int, input().split()))

global answer
answer = 0
sum_ = 0
stack = []
back_tracking(sum_)
print(answer)

메모리: 30840 KB
시간: 1936 ms

반응형

'백준 > Python' 카테고리의 다른 글

[백준 11726] 2xn 타일링 Python  (0) 2022.04.12
[백준 1463] 1로 만들기 Python  (0) 2022.04.12
[백준 11723] 집합 Python  (0) 2022.04.12
[백준 6603] 로또 Python  (0) 2022.04.11
[백준 10971] 외판원 순회 2 Python  (0) 2022.04.11
반응형

외판원 순회 2

티어 : Silver 2
시간 제한 : 2 초
메모리 제한 : 256 MB
알고리즘 분류 : 브루트포스 알고리즘, 백트래킹, 외판원 순회 문제

 

문제

외판원 순회 문제는 영어로 Traveling Salesman problem (TSP) 라고 불리는 문제로 computer science 분야에서 가장 중요하게 취급되는 문제 중 하나이다. 여러 가지 변종 문제가 있으나, 여기서는 가장 일반적인 형태의 문제를 살펴보자.

1번부터 N번까지 번호가 매겨져 있는 도시들이 있고, 도시들 사이에는 길이 있다. (길이 없을 수도 있다) 이제 한 외판원이 어느 한 도시에서 출발해 N개의 도시를 모두 거쳐 다시 원래의 도시로 돌아오는 순회 여행 경로를 계획하려고 한다. 단, 한 번 갔던 도시로는 다시 갈 수 없다. (맨 마지막에 여행을 출발했던 도시로 돌아오는 것은 예외) 이런 여행 경로는 여러 가지가 있을 수 있는데, 가장 적은 비용을 들이는 여행 계획을 세우고자 한다.

각 도시간에 이동하는데 드는 비용은 행렬 W[i][j]형태로 주어진다. W[i][j]는 도시 i에서 도시 j로 가기 위한 비용을 나타낸다. 비용은 대칭적이지 않다. 즉, W[i][j] 는 W[j][i]와 다를 수 있다. 모든 도시간의 비용은 양의 정수이다. W[i][i]는 항상 0이다. 경우에 따라서 도시 i에서 도시 j로 갈 수 없는 경우도 있으며 이럴 경우 W[i][j]=0이라고 하자.

N과 비용 행렬이 주어졌을 때, 가장 적은 비용을 들이는 외판원의 순회 여행 경로를 구하는 프로그램을 작성하시오.

 

입력

첫째 줄에 도시의 수 N이 주어진다. (2 ≤ N ≤ 10) 다음 N개의 줄에는 비용 행렬이 주어진다. 각 행렬의 성분은 1,000,000 이하의 양의 정수이며, 갈 수 없는 경우는 0이 주어진다. W[i][j]는 도시 i에서 j로 가기 위한 비용을 나타낸다.

항상 순회할 수 있는 경우만 입력으로 주어진다.

 

출력

첫째 줄에 외판원의 순회에 필요한 최소 비용을 출력한다.

 

예제 입출력


Algorithm

Back Tracking 이용
1. 입력으로 리스트로 저장해 graph 구현
2. stack에 값 추가
2.1. stack이 비어있으면 현재 숫자 바로 추가
2.2. stack이 비어있지 않으면 stack에 들어있지 않으면서 비용이 0 이상인 값만 추가
3. 재귀함수 호출
4. 재귀함수 호출되면 stack pop
5. stack의 길이가 N이 되면 시작지점으로 돌아올 수 있는지(비용이 0 이상인지) 확인
5.1. 시작지점으로 돌아올 수 있다면 최소비용 갱신

 

Code

def back_tracking(costs):
    global answer
    
    # stack의 길이가 N-1이 되면
    if len(stack) == N:
        # 시작지점으로 돌아올 수 있으면 최소 비용 갱신
        if graph[stack[-1]][stack[0]] > 0:
            costs += graph[stack[-1]][stack[0]]
            if answer > costs:
                answer = costs

    else:
        for num in range(N):
            # stack이 비어있으면
            if not stack:
                if num == 1:
                    return
                # 그냥 추가
                stack.append(num)
                back_tracking(costs)
                stack.pop()
            # stack이 비어있지 않으면 stack에 들어있지 않으면서 비용이 0 이상인 값만 추가
            elif num not in stack and graph[stack[-1]][num] > 0:
                stack.append(num)
                costs += graph[stack[-2]][stack[-1]]
                back_tracking(costs)
                costs -= graph[stack[-2]][stack[-1]]
                stack.pop()
                
N = int(input())
graph = []
for _ in range(N):
    graph.append(list(map(int, input().split())))

global answer
answer = 1000000*N*N
stack = []
costs = 0
back_tracking(costs)
if answer == 1000000*N*N:
    print(0)
else:
    print(answer)

메모리: 30840 KB
시간: 1360 ms

반응형

'백준 > Python' 카테고리의 다른 글

[백준 11723] 집합 Python  (0) 2022.04.12
[백준 6603] 로또 Python  (0) 2022.04.11
[백준 2644] 촌수계산 Python  (0) 2022.04.08
[백준 10819] 차이를 최대로 Python  (0) 2022.04.08
[백준 2606] 바이러스 Python  (0) 2022.04.08
반응형

차이를 최대로

티어 : Silver 2
시간 제한 : 1 초
메모리 제한 : 256 MB
알고리즘 분류 : 브루트포스 알고리즘, 백트래킹

 

문제

N개의 정수로 이루어진 배열 A가 주어진다. 이때, 배열에 들어있는 정수의 순서를 적절히 바꿔서 다음 식의 최댓값을 구하는 프로그램을 작성하시오.

|A[0] - A[1]| + |A[1] - A[2]| + ... + |A[N-2] - A[N-1]|

 

입력

첫째 줄에 N (3 ≤ N ≤ 8)이 주어진다. 둘째 줄에는 배열 A에 들어있는 정수가 주어진다. 배열에 들어있는 정수는 -100보다 크거나 같고, 100보다 작거나 같다.

 

출력

첫째 줄에 배열에 들어있는 수의 순서를 적절히 바꿔서 얻을 수 있는 식의 최댓값을 출력한다.

 

예제 입출력


Algorithm

Back Tracking 이용
1. stack에 포함되어있지 않은 index append
2. 재귀함수 호출
3. 재귀함수 return되면 pop
4. stack의 길이가 N이 되면 식의 최댓값 갱신

 

Code

def back_tracking():
    global answer
    
    # stack의 길이가 N이 되면 식의 최댓값 갱신
    if len(stack) == N:
        sum_ = 0
        for idx in range(1, N):
            sum_ += abs(nums[stack[idx-1]] - nums[stack[idx]])
        if answer < sum_:
            answer = sum_
    else:
        for index in range(N):
            if index not in stack:
                stack.append(index)
                back_tracking()
                stack.pop()
                
N = int(input())
nums = list(map(int, input().split()))

global answer
answer = 0
stack = []
back_tracking()
print(answer)

메모리: 30864 KB
시간: 200 ms

반응형

'백준 > Python' 카테고리의 다른 글

[백준 10971] 외판원 순회 2 Python  (0) 2022.04.11
[백준 2644] 촌수계산 Python  (0) 2022.04.08
[백준 2606] 바이러스 Python  (0) 2022.04.08
[백준 10974] 모든 순열 Python  (0) 2022.04.08
[백준 5598] 카이사르 암호 Python  (0) 2022.04.08
반응형

모든 순열

티어 : Silver 3
시간 제한 : 1 초
메모리 제한 : 256 MB
알고리즘 분류 : 브루트포스 알고리즘, 백트래킹

 

문제

N이 주어졌을 때, 1부터 N까지의 수로 이루어진 순열을 사전순으로 출력하는 프로그램을 작성하시오.

 

입력

첫째 줄에 N(1 ≤ N ≤ 8)이 주어진다. 

 

출력

첫째 줄부터 N!개의 줄에 걸쳐서 모든 순열을 사전순으로 출력한다.

 

예제 입출력


Algorithm

Back Tracking 이용
1. stack이 비어있으면 숫자 바로 append
2. stack이 비어있지 않으면 stack에 포함되어있지 않은 숫자 append
3. 재귀함수 호출
4. 재귀함수 return되면 pop
5. stack의 길이가 N이 되면 stack print

 

Code

# 입력
data = list(map(int, input().split()))

# 입력 값 Dictionary에 저장 (key: 입력 값, value: 횟수)
dict_ = {}def back_tracking():
    
    # stack의 길이가 N이 되면 print
    if len(stack) == N:
        print(' '.join(list(map(str, stack))))
    else:
        for num in range(1, N+1):
            # stack 비어있으면 바로 추가
            if not stack:
                stack.append(num)
                back_tracking()
                stack.pop()
            # stack이 비어있지 않으면 stack에 없는 숫자만 append
            elif num not in stack:
                stack.append(num)
                back_tracking()
                stack.pop()
                
N = int(input())
stack = []
back_tracking()
for i in data:
    if i not in dict_:
        dict_[i] = 1
    else:
        dict_[i] += 1

flag = False # 같은 숫자가 있는 경우 False, 모두 다른 경우 True
for key, value in dict_.items():
    if value == 3:
        print(10000 + key * 1000)
        flag = False
        break
    elif value == 2:
        print(1000 + key * 100)
        flag = False
        break
    else:
        flag = True

if flag:
    print(max(dict_.keys()) * 100)

메모리: 30864 KB
시간: 216 ms

반응형

'백준 > Python' 카테고리의 다른 글

[백준 10819] 차이를 최대로 Python  (0) 2022.04.08
[백준 2606] 바이러스 Python  (0) 2022.04.08
[백준 5598] 카이사르 암호 Python  (0) 2022.04.08
[백준 10973] 이전 순열 Python  (0) 2022.04.08
[백준 2581] 소수 Python  (0) 2022.04.08

+ Recent posts