안경잡이개발자

728x90
반응형

  아래 그래프에는 3개의 연결 요소가 있다.

 

 

  연결 요소의 개수를 세는 코드는 다음과 같다.

 

n = 6
m = 4
# 그래프 정보 초기화
graph = [
    [1, 2],
    [0, 2],
    [0, 1],
    [4],
    [3],
    []
]
# 각 노드의 방문 여부
visited = [False] * n

# 특정 노드에서부터 연결된 모든 노드를 방문 처리
def dfs(x):
    visited[x] = True
    # 현재 노드와 인접한 노드 또한 방문 처리
    for i in graph[x]:
        if not visited[i]:
            dfs(i)

result = 0
for i in range(n):
    # 아직 방문하지 않았다면 방문
    if not visited[i]:
        dfs(i)
        result += 1
print(result)
728x90
반응형

728x90
반응형

  어도비 프리미어(Premiere)에서 특정 시간 범위만 동영상으로 내보내는 방법은 간단하다. 가장 먼저 메뉴 아이콘을 클릭해서 [작업 영역 막대]를 누르자.

 

 

  이후에 다음과 같이 작업 영역 막대가 보이게 된다. 이 작업 영역 막대를 움직여 전체 동영상 클립 중에서 내보낼 구간을 설정할 수 있다.

 

 

  이후에 [파일(F)] - [내보내기] - [미디어]로 이동하여 내보낼 수 있다. 여기에서 다음과 같이 설정했던 작업 영역에 맞게 소스 범위가 정확히 설정되어있는지 다시 확인할 수 있다. 결과적으로 [내보내기]를 눌러서 동영상을 만들면 된다.

 

728x90
반응형

728x90
반응형

대회 링크: codeforces.com/contest/1408

A번 문제: codeforces.com/contest/1408/problem/A

 

  세 개의 수열(Sequence) a, b, c가 존재한다. 이때 수열의 길이는 모두 n으로 동일하다. 또한 각 인덱스에 따른 ai, bi, ci는 서로 다르다. 이때 다음의 조건을 만족하는, 길이가 n인 수열 p를 하나라도 찾으면 된다.

 


[ 문제 해설 ]

 

  기본적으로 ai, bi, ci가 서로 다르다는 조건이 있다. 따라서 일단 a[0]를 출력한 뒤에 그다음부터는 그리디(greedy)하게 하나씩 출력하면 된다. 이때 (순환적으로) 인접한 두 수가 서로 달라지도록 하면 된다. 매번 바로 이전에 출력했던 수를 제외하고 다른 수를 하나 출력하도록 하자. 단, 마지막 수를 출력할 때는 첫째 수 또한 제외하고 출력해야 한다.

 

[ 정답 코드 ]

 

for _ in range(int(input())):
    n = int(input())
    a = list(map(int, input().split()))
    b = list(map(int, input().split()))
    c = list(map(int, input().split()))

    # 첫 번째 수 출력
    now = a[0]
    print(now, end=' ')

    # n - 2개의 수 출력
    for i in range(1, n - 1):
        if now != a[i]:
            now = a[i]
        elif now != b[i]:
            now = b[i]
        elif now != c[i]:
            now = c[i]
    print(now, end=' ')
    
    # 마지막 수 출력
    if now != a[n - 1] and a[n - 1] != a[0]:
        now = a[n - 1]
    elif now != b[n - 1] and b[n - 1] != a[0]:
        now = b[n - 1]
    elif now != c[n - 1] and c[n - 1] != a[0]:
        now = c[n - 1]
    print(now)

 

B번 문제: codeforces.com/contest/1408/problem/B

 

  길이가 n0 이상(non-negative)의 정수로 구성된 비내림차순(non-decreasing) 배열 a가 있다. 우리는 m개의 0 이상(non-negative)의 정수로 구성된 비내림차순(non-decreasing) 배열의 집합 b를 찾는 것이다. 또한 k 값이 입력으로 주어진다. 이때 다음과 같은 조건을 만족하는 가장 작은 m을 찾으면 된다.

 

 

[ 문제 해설 ]

 

  이 문제는 테이블 형태로 그려보면 아이디어를 쉽게 찾을 수 있다. 예를 들어 n = 9, k = 4라고 하자.

 

  a = [0, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4]라고 하면 다음과 같은 수열 b들을 찾을 수 있다.

 

  2 2 3 5 7 11 13 13 17
b1 2 2 3 5 7 7 7 7 7
b2 0 0 0 0 0 4 6 6 10

 

  결과적으로 m의 최솟값은 2이다. 문제 해결 아이디어는 간단하다. 먼저 배열 a에서 서로 다른 원소의 개수를 cnt라고 하자. 이때 cnt를 줄여나가는 방식을 사용한다. b1은 항상 k개만큼의 cnt를 줄일 수 있다. 이후에 b2부터 모든 배열은 (k - 1)개 만큼의 cnt를 줄일 수 있다.

 

[ 정답 코드 ]

 

import math

for _ in range(int(input())):
    n, k = map(int, input().split())

    # 서로 다른 원소 개수
    cnt = len(set(map(int, input().split())))

    if cnt > 1 and k == 1: # (k - 1)이 0이므로 만들 수 없는 경우
        print(-1)
    elif cnt <= k:
        print(1)
    else:
        print(1 + math.ceil((cnt - k) / (k - 1)))

 

C번 문제: codeforces.com/contest/1408/problem/C

 

  길이가 l인 도로가 있다. 이 도로는 좌표 0부터 l까지의 정수로 구성된다. 왼쪽 차는 0에서 시작해서 오른쪽으로 간다. 오른쪽 차는 l에서 시작해서 왼쪽으로 간다. 처음 두 자동차의 속력은 1/s이다. 그리고 n개의 깃발(flag)이 존재한다. 두 자동차는 깃발을 지날 때마다 속력이 1/s씩 증가한다.

 

  결과적으로 두 자동차가 만나는 시간을 출력하면 된다.

 

[ 문제 해설 ]

 

  예를 들어 l = 7이고, 다음과 같이 5개의 깃발이 있다고 해보자.

 

0 1 2 3 4 5 6 7
왼쪽 차 깃발(flag) 깃발(flag) 깃발(flag) 깃발(flag)   깃발(flag) 오른쪽 차

 

  아이디어는 간단하다. 총 n개의 깃발(flag)을 확인하면 된다. 다시 말해 n번을 반복하는데, 반복할 때마다 매번 ① 왼쪽 차 기준으로 다음 깃발까지의 남은 시간, ② 오른쪽 차 기준으로 다음 깃발까지의 남은 시간을 계산하자. 이때 시간이 더 짧은 쪽이 해당 깃발까지 이동하도록 만들면 된다. 그 시간 동안 상대방 차 또한 이동하도록 만들면 된다. 결과적으로 n개의 깃발을 다 처리한 뒤에, 두 자동차가 만나기 위해 걸리는 시간까지 계산해 더해주면 된다.

 

  거리 = 속도 X 시간

 

  위와 같은 공식(거속시)을 이용하여 코드를 작성하면 다음과 같다.

 

[ 정답 코드 ]

 

#include <bits/stdc++.h>
 
using namespace std;
 
int main() {
    int testCase;
    cin >> testCase;
    for (int tc = 0; tc < testCase; tc++) {
        int n, l;
        cin >> n >> l;

        // n개의 깃발(flag) 정보 입력받기
        vector<int> data;
        for (int i = 0; i < n; i ++) {
            int x;
            cin >> x;
            data.push_back(x);
        }

        // 처음 A와 B의 정보 초기화
        long double aPos = 0;
        int aNext = 0;
        int aSpeed = 1;

        long double bPos = l;
        int bNext = n - 1;
        int bSpeed = 1;

        // A와 B가 만나기까지 걸리는 총 시간(time)
        long double time = 0.0;

        // n개의 깃발에 대하여 하나씩 처리
        int cnt = 0;
        while (cnt != n) {
            // A와 B의 다음 깃발까지의 거리
            long double aDistance = data[aNext] - aPos;
            long double bDistance = bPos - data[bNext];

            // A와 B의 다음 깃발까지의 시간
            long double aTime = aDistance / aSpeed;
            long double bTime = bDistance / bSpeed;

            // 더 짧은 시간이 걸리는 자동차를 기준으로 이동
            if (aTime <= bTime) {
                aPos = data[aNext];
                bPos -= aTime * bSpeed;
                aNext += 1;
                aSpeed += 1;
                time += aTime;
            }
            else {
                bPos = data[bNext];
                aPos += bTime * aSpeed;
                bNext -= 1;
                bSpeed += 1;
                time += bTime;
            }
            cnt++;
        }

        // 마지막으로 A와 B가 서로 만나도록 하기
        long double distance = bPos - aPos;
        time += distance / (aSpeed + bSpeed);

        cout.precision(15);
        cout << fixed;
        cout << time << '\n';
    }
}

 

D번 문제: codeforces.com/contest/1408/problem/D

 

[ 정답 코드 ]

 

n, m = map(int, input().split())

robbers = []
lights = []

for i in range(n):
    a, b = map(int, input().split())
    robbers.append((a, b))

for i in range(m):
    c, d = map(int, input().split())
    lights.append((c, d))

v = [0] * 1000002

for a, b in robbers:
    for c, d in lights:
        # 현재 robber보다 light의 x가 더 크거나 같다면 감시 가능
        if a <= c:
            # 그때 robber가 y 방향으로 얼마만큼 이동해야 숨을 수 있는지 계산
            v[c - a] = max(v[c - a], d - b + 1)

result = 1000001 # 1000001만큼 움직이는 것이 최악의 경우
dy_max = 0 # 가장 큰 dy 값

# 1000001부터 0까지 1씩 줄여가며, 모든 dx에 대하여
for dx in range(1000001, -1, -1):
    dy_max = max(dy_max, v[dx])
    # (dx + dy_max) 값이 가장 작은 경우를 출력
    result = min(result, dx + dy_max)

print(result)
728x90
반응형

728x90
반응형

  PuTTY는 대표적인 원격 접속 프로그램이다. 가장 많이 사용되는 프로토콜인 SSH, Telnet, Serial 등을 지원한다. 물론 XShell과 같은 고급 소프트웨어도 있지만 간단히 원격 접속을 해야 할 때는 PuTTY만큼 편한 게 없다.

 

 

  ▶ PuTTY 설치 경로: www.putty.org/

 

  접속 이후에 다운로드 페이지로 이동한다.

 

 

  다음과 같이 설치 프로그램을 다운로드하면 된다.

 

 

  [Next] 버튼을 눌러 Default 설정으로 설치를 진행해보자.

 

 

 

 

  결과적으로 다음과 같이 설치가 진행된다.

 

 

  설치가 완료되면 PuTTY 프로그램을 실행할 수 있다.

 

728x90
반응형

728x90
반응형

  ODROID C1의 Ubuntu OS를 살펴보자.

 

  ▶ ODROID C1 운영체제: wiki.odroid.com/odroid-c1/os_images/ubuntu/ubuntu

 

  확인해 보면 Ubuntu OS의 버전에 상관 없이 리눅스 커널(Kernel) 3.10 버전을 사용하고 있다. ODROID C1는 USB OTG 기능을 제공하기 때문에 USB 디바이스 기능을 제공할 수 있다는 장점이 있다. 하지만 커널 3.10 버전에 멀티 가젯(multi-gadget) 관련 오류가 있다. 그래서 필자는 더 높은 버전의 커널이 필요한 상황이다.

 

 

  ODROID C1는 공식적으로 최신 커널을 지원하지는 않는다. 그래서 최신 커널을 제공하는 비공식 Ubuntu OS를 설치할 수 있다. 이를 위해 Armbian 사이트에 방문하면 된다. Armbian은 다양한 ARM 개발 보드 전용 운영체제를 제공한다. 대표적으로 Ubuntu 등을 제공한다. 예를 들어 ODROID C1+는 2020년 현재 공식적으로 Kernel 3.10 버전을 제공한다.

 

  ▶ ODROID C1 Armbian: www.armbian.com/odroid-c1/

 

Odroid C1 – Armbian

Armbian Cookies Policy Our Website uses cookies to improve your experience. Please visit our Odroid C1 page for more information about cookies and how we use them. Close

www.armbian.com

 

  여기에서 [Archived versions] 링크로 이동하면 다양한 OS 이미지를 받을 수 있다.

 

 

  이것을 그대로 다운로드 받아서 SD 카드에 설치하면 되는 것 같다. 다만 한 가지 문제가 있다. Armbian 사이트에 따르면 이 이미지를 설치해도 HDMI 출력을 지원하지 않는다고 한다. 즉 OS를 설치한 뒤에 부팅을 해도 화면이 안 나온다는 의미다. 아래 설명을 보면 시리얼 콘솔(serial console)만 지원한다고 한다.

 

 

  실제로 시리얼 콘솔(Serial Console)을 이용하는 방법을 확인해 보자. ODROID C1 사용자 매뉴얼에 따르면 USB-UART 모듈 키트가 필요하다고 한다. 관련 문단을 가져오면 다음과 같다.

 

 

  USB-UART는 다음과 같이 생긴 부품이다. 생각보다 가격이 비싸서 놀랐다.

 

  ▶ USB-UART Module Kit: www.hardkernel.com/ko/shop/usb-uart-module-kit/

 

 

  그래서 이럴 줄 알았으면 처음부터 ODROID C4를 구매하는 편이 좋았을 것 같다. 2020년 기준으로 ODROID C4는 리눅스 커널 4.9 버전을 사용하고 있으며, 마찬가지로 USB OTG 기능을 제공하기 때문이다. 아무튼 USB-UART 모듈 키트를 구매하면 ODROID C1에 최신 커널을 무리 없이 업로드할 수 있을 것 같다. 어차피 나는 ODROID C1를 USB 디바이스 개발용으로 쓰는 거라서 다른 문제들은 큰 이슈가 되지 않을 것이다. 만약 ODROID C1에 모니터를 연결하고 일반적인 컴퓨터로 쓰고 싶은 사람이라면 저 최신 커널을 그대로 이용하면 HDMI가 동작하지 않을 것이다. 필자는 어떻게 해야 할 지 고민된다.

728x90
반응형

728x90
반응형

  Advanced IP Scanner는 IP 기반의 무료 네트워크 스캐닝 소프트웨어입니다. 일반적으로 내부망에서 어떤 IP를 어떤 컴퓨터가 쓰고 있는지를 확인하기 위해 간단히 사용할 수 있습니다. 추가적으로 RDP(Remote Desktop Protocol) 등의 기능도 제공합니다. 특히 회사나 학교에서는 사람마다 특정 IP를 사용하기로 약속하는 경우가 많으므로, 이러한 스캐닝 소프트웨어를 효과적으로 이용할 수 있습니다. 혹은 라즈베리파이(Raspberry Pi)와 같은 보조 컴퓨터를 함께 사용하는 상황 등에서 자주 이용하게 되는 것 같습니다.

 

  공식 사이트에서 제공하는 사용 예시 이미지는 다음과 같습니다.

 

 

  ▶ Advanced IP Scanner 다운로드: www.advanced-ip-scanner.com/ 

 

  해당 소프트웨어를 다운로드 하기 위해서는 공식 사이트에 접속하신 뒤에 [무료 다운로드] 버튼을 누르시면 됩니다.

 

 

  가장 먼저 설치 언어를 설정할 수 있습니다.

 

 

  여기에서 굳이 설치하지 않고 [실행(R)] 버튼을 눌러서 바로 실행할 수도 있습니다. 프로그램을 두고두고 오래 사용하고 싶은 분이라면 [설치(I)]를 진행해주세요. 저는 그냥 바로 실행하겠습니다.

 

 

  이후에 약관에 동의하고 실행하시면 됩니다.

 

 

  이제 다음과 같이 스캔을 수행할 IP 대역을 입력할 수 있습니다.

 

 

  결과적으로 특정 IP 대역에 대하여 스캐닝(Scanning)을 수행하면 다음과 같이 각각의 IP를 쓰고 있는 컴퓨터에 대한 정보가 출력됩니다.

 

 

  참고로 현재 자신이 포함되어 있는 네트워크가 아닌 원격지에서 스캔을 수행하는 경우에는 한정적인 정보만 나오며, 제조업체(manumanufacturer) 정보가 출력되지 않을 수 있습니다.

728x90
반응형

728x90
반응형

  크롬(Chrome) 브라우저를 이용해 파일을 다운로드 받으면 기본적인 경로는 C:\Users\{사용자명}\Downloads입니다. 만약 이 경로를 바꾸고 싶다면 먼저 [설정] 페이지로 이동하시면 됩니다.

 

 

  이후에 [고급] 탭으로 이동하여 [다운로드] 섹션의 위치(경로)를 눌러 변경하시면 됩니다.

 

 

  저는 다음과 같이 E 드라이브 내의 한 경로로 변경하였습니다.

 

 

  이후에 다운로드를 한 모든 파일은 앞서 설정했던 경로에 저장되는 것을 알 수 있습니다.

 

728x90
반응형

728x90
반응형

여러 시퀀스에 효과 한꺼번에 붙여넣기

  어도비 프리미어(Premiere)에서 효과를 복사해 한꺼번에 여러 시퀀스(Sequence)에 붙여넣고 싶을 때가 있다. 하나의 시퀀스에 적용된 특정한 효과를 복사할 때는 그냥 우클릭해서 [복사] 버튼을 누르면 된다.

 

 

  이후에 복사된 효과를 붙여넣고 싶은 시퀀스를 전부 드래그 앤 드롭(Drag & Drop)해서 [컨트롤(Ctrl) + V]를 이용해 붙여넣으면 된다.

 

 

  붙여넣기가 완료되면 다음과 같이 효과가 모두 적용된 것을 알 수 있다.

 

여러 시퀀스에서 효과 한꺼번에 제거하기

  만약에 여러 시퀀스에 적용된 효과(Effect)를 한꺼번에 제거하고 싶을 때는 시퀀스를 선택한 뒤에 [특성 제거] 버튼을 눌러서 원하는 특성을 제거할 수 있다.

 

 

  [특성 제거] 탭에서는 제거하고자 하는 특성에 체크하면 된다. 그러면 체크된 효과는 모두 제거된다. 만약 노이즈 제거 효과를 제거하고 싶다면, 다음과 같이 [노이즈 제거]에 체크하여 [확인] 버튼을 누르자.

 

 

  그러면 다음과 같이 선택되었던 모든 시퀀스에 대하여 효과가 제거된다.

 

728x90
반응형

728x90
반응형

  어도비 프리미어 프로(Adobe Premiere Pro)를 이용하면 영상에서 간단히 노이즈(Noise)를 제거할 수 있다. 효과 중에서 [노이즈 제거]를 이용하여 간단하게 노이즈를 줄이는 실습을 해보자.

 

 

  효과를 드래그 앤 드롭(Drag & Drop)해서 다음과 같이 영상에 효과를 적용할 수 있다.

 

 

  다음과 같이 기본적인 설정으로 40%가 적용되어 있습니다. 사실 이 수치는 일반적인 영상에서 아주 큰 수치라서 목소리도 많이 제거될 수 있다. 그래서 필자의 경우 일반적으로 5~10% 정도로 설정한다.

 

 

  개인적으로 필자가 강의 영상에서 사용하는 노이즈 제거(DeNoiser) 설정은 다음과 같다. 대략 5% 정도로 노이즈를 약하게 제거할 수 있도록 하고, 다시 음량을 조금 높이기 위해 게인(Gain)1dB 정도로 설정한다.

 

728x90
반응형

728x90
반응형

  동영상 정보를 빠르고 간단하게 확인할 수 있도록 도와주는 프로그램으로는 MediaInfo가 있다. 무료 프로그램이며, 손쉽게 다운로드 받아 사용할 수 있다.

 

  ▶ MediaInfo 다운로드www.videohelp.com/software/MediaInfo

 

  MediaInfo는 비디오(Video)나 오디오(Audio) 파일의 기본적인 정보를 보여주는 프로그램이다. 기본적인 비디오의 코덱 정보, 프레임율(Frame Rate) 등의 정보를 보여준다. 해당 링크에 접속하면 다음과 같이 운영체제에 맞는 최신 버전을 받을 수 있다. 필자는 다음과 같이 윈도우(Windows) 운영체제 전용 설치 프로그램을 받았다.

 

 

  설치 프로그램을 다운로드 받아서 실행하면 다음과 같다.

 

 

  기본적인 설정 그대로 설치를 진행하면 된다.

 

 

  설치를 완료한 뒤에 실행할 수 있다.

 

 

  프로그램을 처음 실행하면 다음과 같이 기초 환경 설정을 진행할 수 있다. 다음과 같이 [언어]한국어로 설정하면 한국어로 이용할 수 있다.

 

 

  이후에 MediaInfo가 다음과 같이 실행되는 것을 알 수 있다.

 

 

  하나의 동영상 파일을 드래그 앤 드롭(Drag & Drop) 하면 다음과 같이 동영상 정보를 확인할 수 있다. 기본적으로 동영상에 포함되어 있는 비디오와 오디오 정보가 각각 나오는 것을 확인할 수 있다. 대개 동영상의 비트율(BPS, Bit Per Second)이나 코덱 정보, 비디오 및 오디오 품질을 확인하기 위해 사용할 수 있다.

 

  또한 오른쪽 아래에 있는 [화살표(→)] 버튼을 눌러서 다른 보기를 선택할 수 있다.

 

 

  다음과 같이 [트리]로 설정해보자.

 

 

  그러면 다음과 같이 더욱 자세한 내용을 확인할 수 있다. 

 

728x90
반응형