3월 31, 2024

[유튜브 동영상 편집] 영상편집 프로그램 추천! (다빈치 리졸브 다운로드 방법)

1. 영상편집 프로그램 추천

요즘 유튜브 하시는 분들 많으시죠? 유튜브를 시작할 때 가장 큰 고민이 어떠한 영상 프로그램으로 편집을 할지일텐데요! 요즘에는 여러 영상편집 툴이 많이 개발되어서 전문가가 아니더라도 누구나 쉽게 편집을 할 수 있답니다!

 

오늘 제가 추천할 영상편집 프로그램은 "다빈치 리졸브" 라는 프로그램이에요!

다빈치 리졸브는 무료, 유료 버전이 둘 다 존재하는데요 무료 버전으로도 충분히 대부분의 편집 기능이 지원됩니다. 자막넣기, bgm 넣기, 화면에 그림 넣기, 화면 전환 등 다양한 효과를 쉽게 접근할 수 있어서 쉽게 영상편집을 할 수 있어요! (제 경험을 바탕으로 한 거에요! 처음 유튭 영상편집을 할 때 처음으로 사용한 프로그램이 다빈치 리졸브입니다!)


 

2. 다빈치 리졸브 설치 방법 

그러면 설치를 해봐야 겠죠?

 

우선 아래 링크로 접속해주세요!

 

www.blackmagicdesign.com/kr/products/davinciresolve/


위 링크에 들어가면 다빈치 리졸브 홈페이지로 연결이 될텐데요,

 

위 링크로 들어가셔서 조금 스크롤을 내리다 보면,

 


다운로드 화면

위와 같이 지금 다운로드 라는 버튼이 나온 화면을 볼 수 있을거에요

 

그러면 "지금 다운로드" 버튼을 클릭해줍니다.

 



다운로드 화면

 

여기서 저는 DaVinci Resolve 16.2.8에서 Windows를 눌러서 다운로드를 받아주었어요. studio 버전과 일반 버전의 차이는 studio 버전이 유료버전, 일반버전이 무료버전이라는 거에요!

 

왼쪽 하단의 DaVinci Resolve 16.2.8을 자신의 컴퓨터 os에 맞게 다운받으면 됩니다! 

 

유료버전은 더 지원하는 기능이 많으니 만약 유료버전을 구매하고 싶다면 오른쪽의 DaVinci Resolve Studio 16.2.8로 다운을 받으면 되겠어요!

 

일반 유튜브 용이라면 16 버전도 충분하기 때문에 아마 아래쪽 두개에서 고민을 하면 될 거에요!

 

자신에게 맞는 버전을 설치해주면 다빈치 리졸브 프로그램이 열릴텐데 그 이후의 사용법부터는 이후 포스팅에서 차근차근 다루어보도록 하겠습니다~


3월 31, 2024

[백준] 16968번 차량 번호판1 조합을 활용하여 간단하게 해결해보기

1. 문제

www.acmicpc.net/problem/16968

문제는 위의 링크에 들어가면 확인해볼 수 있다.


2. 풀이

이 문제를 푸는 여러 방법이 있을 수 있는데 오늘 여기서는 재귀로 푸는 법 말고 조합을 활용해서 쉽게 풀 수 있는 법을 소개해보도록 하겠다. 

 

조합을 활용한다는 것은 각 자리의 가능한 경우의 수를 계산해서 곱해준다는 것이다. 

만약 해당 자리의 알파벳이 'c'라면 알파벳이 들어가야 하므로 26가지 경우가 있을 수 있고, 만약 'd'라면 숫자가 들어가야 하므로 10가지 경우가 있을 수 있다. 여기서 추가로 문제에서 동일한 문자나 숫자가 두 번 연속해서 나올 수 없다고 했기 때문에 두 자리가 모두 'c'거나 모두 'd'라면 경우의 수를 한 가지 줄여서 계산해주어야 한다. 

 

이렇게 해서 전체 총 경우에다가 계속 경우의 수를 곱해나가면 쉽게 해결할 수 있다.


3. 코드

전체 코드는 아래와 같다.

import java.util.*;
public class Main {
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        String s = sc.next();
        int ans = 1;
        for (int i=0; i<s.length(); i++) {
            int count = (s.charAt(i) == 'c' ? 26 : 10);
            if (i > 0 && s.charAt(i) == s.charAt(i-1)) {
                count --; //같은 문자열, 숫자 제외하기 위해서
            }
            ans = ans * count;
        }
        System.out.println(ans);
    }
}

 

알고리즘은 여러가지 방법으로 풀어보는 연습을 해야 실력도 늘고 생각하는 힘도 길러지는 것 같다. 한 가지 방법으로 풀어봤더라도 다양하게 연습해보자.


3월 31, 2024

[백준] 2110번 공유기 설치 문제 이분탐색으로 쉽게 풀어보기

1. 문제

www.acmicpc.net/problem/2110

문제는 위의 링크를 클릭하면 확인할 수 있다.


2. 풀이

이 문제 또한 이분탐색으로 해결할 수 있다. 공유기 사이의 거리를 이분탐색을 통해 구해보면서 c 개를 설치할 수 있는 거리가 어디인지를 찾아보는 것이다.

 

이분탐색의 경우에는 초기의 left 와 right 값을 잘 정하는 것이 중요한데 여기서는 left의 값은 1로 잡고 (가장 최소의 값이 거리 1이기 때문) right의 값은 집의 위치를 정렬한 다음에 가장 끝 집과 첫 집의 거리로 잡으면 된다. (이것이 거리의 가장 최댓값)

 

그런다음에 이분탐색을 진행하고,

 

만약 가장 인접한 두 공유기 사이의 거리를 통해 주어진 공유기 c개를 설치할 수 있다면 left의 값을 mid+1로 조정, 설치할 수 없다면 right의 값을 mid-1로 조정한다.

 

공유기를 설치할 수 있는지를 판단하는 함수를 하나 만들어주었다.

public static boolean check(int mid){
        int count=1; 
        int first=place[0];
        for(int location: place){
            if (location-first>=mid){
                count++;
                first=location;
            }
        }
        return (count>=k);
    }

여기서 count는 설치할 수 있는 공유기의 개수를 의미하고 기준이 되는 place 의 값을 변경하면서 공유기를 설치할 수 있는지 세어주었다. 만약 count의 값이 문제에서 주어진 c 값보다 크거나 같다면 true를 return 아니면 false를 return 해준다.

 


위의 check 함수를 이용한 이분탐색 부분의 코드는 아래와 같다.

int ans=1;  //거리 최소 1
        int left=1;
        int right=place[n-1]-place[0]; //최대 거리
        while(left<=right){
            int mid=(left+right)/2;
            if (check(mid)){
                ans=Math.max(ans, mid);
                left=mid+1;
            }
            else{
                right=mid-1;
            }
        }

여기서 이분탐색을 사용하기 위해서는 반드시 정렬이 된 상태여야 하기 때문에 문제에서 입력받은 place를 먼저 정렬한 뒤 사용해야 한다.


3. 코드

이를 활용한 전체 코드는 아래와 같다. 

import java.util.*;

public class Main{
    static int k;
    static int []place;
    public static boolean check(int mid){
        int count=1; 
        int first=place[0];
        for(int location: place){
            if (location-first>=mid){
                count++;
                first=location;
            }
        }
        return (count>=k);
    }
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        k=sc.nextInt();
        place=new int[n];
        for(int i=0; i<n; i++){
            place[i]=sc.nextInt();
        }
        Arrays.sort(place);
        int ans=1;  //거리 최소 1
        int left=1;
        int right=place[n-1]-place[0]; //최대 거리
        while(left<=right){
            int mid=(left+right)/2;
            if (check(mid)){
                ans=Math.max(ans, mid);
                left=mid+1;
            }
            else{
                right=mid-1;
            }
        }
        System.out.println(ans);
        
    }
}

 


이분탐색처럼 보이지 않는 문제도 이분탐색을 활용하면 쉽게 해결할 수 있는 경우가 많다. 위의 코드와 비슷한 문제 2805번 나무 자르기 문제도 그 예시중 하나다.


3월 31, 2024

[백준] 1654번 랜선 자르기 문제 이분탐색 활용해서 풀어보기

1. 문제

www.acmicpc.net/problem/1654


문제는 위의 링크에 들어가면 볼 수 있다.


2. 풀이

이 문제는 이분탐색을 활용해서 해결할 수 있는 문제이다. 

사실 모든 랜선의 길이를 하나씩 다 구해보는 방법도 있겠지만 그러면 시간이 오래걸리기 때문에 이분탐색으로 해서 시간을 줄이는 방법을 사용하면 된다.

 

처음에 left의 값은 1로 시작하고 right의 값은 랜선 길이 중에서 최대길이로 시작을 한다. ok라는 함수를 만들어서 랜선의 길이가 문제에서 주어진 개수보다 많거나 같으면 true를 return하고 작으면 false를 return한다.

public static boolean ok(long mid){
        int cnt=0;
        for(int i=0; i<a.length;i++){
            cnt+=(a[i]/mid);
        }
        return (cnt>=k);
    }

 

만약 return 값이 true라면 숫자를 증가시켜도 된다는 뜻이므로 left의 값을 mid+1로 조정하고, false라면 숫자를 낮추어야 한다는 뜻이므로 right를 mid-1로 조정한다. 

 

 

이를 반영한 이분탐색 부분의 코드는 아래와 같다.

 long ans=0;
        long left=1;
        long right=max;
        while(left<=right){
            long mid=(left+right)/2;
            if (ok(mid)){//원하는 개수 이상으로 만들 수 있음
                left=mid+1;
                ans=Math.max(ans, mid);
            }
            else{
                right=mid-1;
            }
        }

이렇게 이분탐색을 진행하면 빠르게 문제를 해결할 수 있다.

 

3. 코드 

전체 코드는 아래와 같다. 

import java.util.*;

public class Main{
    static int k;
    static long a[];
    public static boolean ok(long mid){
        int cnt=0;
        for(int i=0; i<a.length;i++){
            cnt+=(a[i]/mid);
        }
        return (cnt>=k);
    }
        
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
         k=sc.nextInt();
        a=new long[n];
        long max=0; //가장 길이가 긴 랜선 길이 저장
        for(int i=0; i<n; i++){
            a[i]=sc.nextInt();
            max=Math.max(max, a[i]);
        }
        long ans=0;
        long left=1;
        long right=max;
        while(left<=right){
            long mid=(left+right)/2;
            if (ok(mid)){//원하는 개수 이상으로 만들 수 있음
                left=mid+1;
                ans=Math.max(ans, mid);
            }
            else{
                right=mid-1;
            }
        }
        System.out.println(ans);
        
    }
}

3월 31, 2024

[안드로이드] 앱 켜자마자 특정 URL로 이동하기

앱 실행 후 다른 url로 이동하기

앱을 틀자마자 다른 URL로 이동하고 싶을 때 혹은 웹사이트를 만들어서 앱을 통해서도 접근할 수 있게 만들고 싶을때 코드를 단순히 추가하면 쉽게 해결할 수 있다. 

 

나는 코틀린으로 코드를 작성했기 때문에 

MainActivity.kt 파일에서 

 

import android.content.Intent
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val i = Intent(Intent.ACTION_VIEW)
        i.data = Uri.parse("https://programmingstory.com/")
        startActivity(i)
        setContentView(R.layout.activity_main)
    }
}

위와 같이 코드를 작성해주면 된다.

 

그러면 네이버 앱을 틀었을때 바로 내가 원하는 URL로 이동할 수 있다.


3월 25, 2024

[백준] 1517번 버블 소트 문제 Merge Sort로 풀어보기 (버블 소트로는 풀 수 없는 이유?)

1. 문제

www.acmicpc.net/problem/1517

문제는 위의 링크에 들어가면 확인할 수 있다.


2. 풀이

이 문제는 버블 소트를 할 때 수를 바꾸는 과정이 몇 번 있는지를 묻는 문제이다. 하지만 이것을 실제 Bubble Sort대로 풀면 시간초과가 나게 될 것이다. 왜냐하면 버블소트는 시간복잡도 O(N^2) 이기 때문에 문제에서 주어진 조건을 초과하게 된다. 

 

따라서 이 문제는 시간복잡도 O(NlogN)인 merge sort를 활용하여서 풀 수 있다. 

 

버블 소트는 index i, j에 대해서 i<j인데 a[i] > a[j] 일때 두 수를 바꾸어주는 알고리즘을 의미한다. 

그래서 이를 merge sort라고 생각하면, 두 그룹을 합쳐줄 때 버블 소트에서 두 수를 바꾸어주는 count를 세어 줄 수 있다.

 

다시 말해서,


위와 같은 두 그룹을 merge sort를 통해서 합쳐준다고 생각하면 첫 그룹의 7과 두번째 그룹의 1을 비교해서 1이 먼저 앞으로 들어가게 된다. 

Bubble Sort라고 생각해보면 7, 9, 1, 3이 다 합쳐져있었을 것이고 1을 기준으로 7과 1이 한번 교환되었을 것이고, 9과 1이 한번 더 교환되었을 것이다. 그러면 1 기준으로 두 번의 숫자 교환이 이루어졌던 것이다. 

우리는 merge sort를 통해서 구현하고 있었으니 이를 merge sort로 생각해보면 두 번째 그룹인 1이 가장 처음에 들어갈 때 앞에 남아있는 그룹의 원소 개수만큼 숫자의 교환이 이루어지는 것이다. 여기서는 1이 가장 먼저 정렬될 때 첫 번째 그룹에 7,9 이렇게 두 개의 숫자가 남아있으니 답에는 2가 더해지게 되는 것이다. 마찬가지로 3의 경우에도 3이 정렬될 때 첫 번째 그룹에 두 개의 숫자가 남아있으니 답에는 추가로 2만큼 더해주어야 한다.

 


3. 코드

이를 코드로 구현한 것은 아래와 같다.

 

import java.util.*;
import java.io.*;

public class Main{
    static int a[];
    public static long go(int start, int end){
        if (start==end){
            return 0;
        }
        int mid=(start+end)/2;
        long ans=go(start, mid)+go(mid+1, end);
        int [] tmp=new int[end-start+1];
        { //두 그룹을 합칠 때 merge
            int i=start;
            int j=mid+1;
            int k=0;
            while(i<=mid || j<=end){
                if (i<=mid && (j>end||a[i]<=a[j])){
                    tmp[k++]=a[i++];
                }else{
                    ans+=(long)(mid-i+1);  //두번째 그룹의 숫자가 들어갈 때 
                    tmp[k++]=a[j++];
                }
            }
            
        }
        for (int i=start; i<=end; i++) {
            a[i] = tmp[i-start];
        }
        return ans;
    }
    public static void main(String[] args) throws IOException{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        int n=Integer.valueOf(br.readLine());
        a=new int[n];
        String s[]=br.readLine().split(" ");
        for(int i=0; i<n; i++){
            a[i]=Integer.valueOf(s[i]);
        }
        System.out.println(go(0, n-1));
    }
}

merge sort의 구현을 그대로 따라주었고 다른 점은 두 번째 그룹의 숫자를 tmp라는 배열에 담을 때 첫 번째 그룹의 원소개수를 정답에 추가해주어야 한다는 점이다. 


3월 25, 2024

[백준] 2263번 트리의 순회 문제 풀어보기

1. 문제

www.acmicpc.net/problem/2263

문제는 위의 링크에 들어가면 볼 수 있다.


2. 풀이

이 문제는 간단히 말해서 인오더와 포스트오더가 주어졌을때 프리오더로 출력할 수 있냐는 문제이다. 

우선 트리의 순회는

https://www.programmingstory.com/2024/02/blog-post_11.html

위의 포스팅에서 다루었기 때문에 트리에 대해 처음 접하는 사람들은 위의 포스팅을 먼저 읽고 오자.


우선 인오더의 경우에는 왼쪽 자식 노드를 방문한 뒤, 루트 노드를 방문하고, 오른쪽 자식 노드를 방문하는 순서이고,

포스트오더의 경우에는 왼쪽 자식노드와 오른쪽 자식 노드를 모두 방문한 뒤 마지막에 루트 노드를 방문하는 경우를 뜻한다.

 

따라서 우리가 확실하게 알 수 있는 것은 포스트오더의 마지막에는 항상 루트 노드가 나온다는 것이다. 

그런 다음에 인오더의 배열에서 루트 노드를 찾고, 루트 노드를 기준으로 왼쪽 자식 노드로 또 다시 재귀로 함수를 호출하고, 오른쪽 노드들로 다시 재귀함수를 호출하면 된다. 그러면서 프리오더를 구현해야 하기 때문에 루트 노드는 먼저 출력해주고, 다음에 왼쪽 자식 노드들 호출, 오른쪽 자식 노드들을 호출해주면 되는 것이다.

 


3. 코드

전체 코드는 아래와 같다.

import java.util.*;

public class Main{
    static int inorder[];
    static int postorder[];
    static int location[];
    static void solve(int in_s, int in_e, int post_s, int post_e ){
        if (in_s>in_e||post_s>post_e) return;
        int root=postorder[post_e];
        System.out.print(root+" ");
        int index=location[root]; //프리오더의 index
        int left_count=index-in_s; 
        solve(in_s, index-1, post_s, post_s+left_count-1);
        solve(index+1, in_e, post_s+left_count, post_e-1);
    }
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        inorder=new int[n];
        postorder=new int[n];
        for(int i=0; i<n; i++){
            inorder[i]=sc.nextInt();
        }
        for(int i=0; i<n; i++){
            postorder[i]=sc.nextInt();
        }
        location=new int[100001];
        for(int i=0; i<n; i++){
            location[inorder[i]]=i; //숫자를 적으면 바로 index가 나오게
        }
        solve(0, n-1, 0, n-1);
    }
}

 

여기서 location이라는 배열을 구한 것은 매번 루트 노드가 몇 번째 index에 위치해있는지를 찾지 않기 위함이다. 그러면 시간복잡도가 매우 높게 나오기 때문에 애초에 배열을 사용해서 해당 숫자를 배열의 index로 주면 바로 몇 번째 index에 루트 노드가 위치해있는지를 판단할 수 있도록 코드를 구현했다.

 

solve 함수에서 in_s 는 인오더의 시작 index, in_e는 인오더의 끝 index, post_s는 포스트오더의 시작 index, post_e는 포스트오더의 끝 index를 뜻한다. 이후에 루트 노드를 찾아주고 인오더 배열 기준으로 왼쪽 오른쪽을 재귀적으로 호출해주면 프리오더를 구현할 수 있다.