SMALL

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

 

29719번: 브실이의 불침번 근무

브실이가 하루 이상 불침번에 들어갈 경우의 수를 $1\,000\,000\,007$로 나눈 나머지를 출력한다.

www.acmicpc.net

 


  • 문제풀이

 

열심히 종이에 적다보니 규칙을 찾게 되었다.

∑nCr*(m-1)^(n-r)이 브실이가 근무를 하는 경우의 수임을 알게 되었다.

 

 

 

그래서  브실이가 들어가는 경우의 수를 모두 합하여 구하려고 했으나 시간초과가 걸렸다.

 

# -*- coding: utf-8 -*-
import sys
MOD = 1000000007

def calculate_sigma(N, M):
    result = 0
    combination_values = [0] * (N + 1)
    exponent_values = [0] * (N + 1)
    
    combination_values[0] = 1
    exponent_values[0] = 1
    
    for R in range(1, N + 1):
        # 조합 계산에서 나눗셈을 정수 나눗셈으로 변경
        combination_values[R] = (combination_values[R - 1] * (N - R + 1) // R)
        exponent_values[R] = (exponent_values[R - 1] * (M - 1))
    
    for R in range(1, N + 1):
        result = (result + combination_values[R] * exponent_values[N - R])
    
    # 최종 결과에서 모듈러 연산
    result %= MOD
    
    return result

N, M = map(int, sys.stdin.readline().split())

sigma_result = calculate_sigma(N, M)
sys.stdout.write(str(sigma_result % MOD) + '\n')

 

 

시간초과를 해결하기 위해서는 브실이가 근무를 투입하는 경우의 수가 아니라 브실이가 근무를 들어가지 않는 수를 구해야했다.

이는 수식으로 M^N - (M-1)^N 로 나타낼 수 있다.


  • 코드 1
# -*- coding: utf-8 -*-


MOD = 1000000007  # 나눌 모듈러 값

# 필요한 모듈 import
import sys

# 입력 받기
N, M = map(int, sys.stdin.readline().split())

# M^N - (M-1)^N 계산
result = (pow(M, N, MOD) - pow(M - 1, N, MOD)) % MOD

# 결과 출력
sys.stdout.write(str(result) + '\n')

 


  • 후기

규칙을 찾아 수식으로 만들어내는 과정이 재밌던 문제이다.

LIST
SMALL

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

 

17268번: 미팅의 저주

인하대 컴퓨터 공학과에 재학 중인 이산이는 오랜만에 미팅을 나가 볼까 한다. 미팅은 N명이 원탁에 앉아서 진행된다고 한다. 질투가 난 이산이 친구 명기는 X의 저주를 걸었다. 그 저주는 N명이

www.acmicpc.net


  • 문제풀이

조합을 이용해서 풀어낸다.


  • 코드 1
using System;

class Program
{
    const long mod = 987654321;

    static void Main(string[] args)
    {
        int n = int.Parse(Console.ReadLine());
        n = n / 2;
        long[] memo = new long[n + 1];
        memo[0] = 1;

        for (int i = 1; i <= n; i++)
        {
            memo[i] = 0;
            for (int k = 0; k < i; k++)
            {
                memo[i] += ((memo[k] % mod) * (memo[i - 1 - k] % mod)) % mod;
            }
            memo[i] %= mod;
        }

        Console.WriteLine(memo[n] % mod);
    }
}

 


  • 후기

통계는 언제나 자주 사용되는 것 같다.

LIST

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

[C#]백준 2579번: 계단 오르기  (0) 2023.09.25
[C#]백준 24511번: queuestack  (0) 2023.08.25
[C#]백준 16928번: 뱀과 사다리 게임  (0) 2023.08.25
[C#]백준 1149번: RGB거리  (0) 2023.08.25
[C#]백준 1912번: 연속합  (0) 2023.08.25
SMALL

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

 

2579번: 계단 오르기

계단 오르기 게임은 계단 아래 시작점부터 계단 꼭대기에 위치한 도착점까지 가는 게임이다. <그림 1>과 같이 각각의 계단에는 일정한 점수가 쓰여 있는데 계단을 밟으면 그 계단에 쓰여 있는 점

www.acmicpc.net


  • 문제풀이

동적계획법을 사용하여 계산해준다.

두가지의 경우로 나눌 수 있다.

 

1경우: 1칸, 2칸, 4칸(두칸 가고 한칸 건너띄기)

2경우: 1칸, 3칸(한칸 가고 한칸 건너띄기)


  • 코드 1
using System;

class MainClass
{
    public static void Main(string[] args)
    {
        int n = int.Parse(Console.ReadLine());
        int[] stairs = new int[n + 1];
        int[] dp = new int[n + 1];

        for (int i = 1; i <= n; i++)
        {
            stairs[i] = int.Parse(Console.ReadLine());
        }

        dp[1] = stairs[1];
        if (n >= 2)
            dp[2] = stairs[1] + stairs[2];

        for (int i = 3; i <= n; i++)
        {
            dp[i] = Math.Max(dp[i - 2] + stairs[i], dp[i - 3] + stairs[i - 1] + stairs[i]);
        }

        Console.WriteLine(dp[n]);
    }
}

 


  • 후기

동적계획법은 문제가 어느정도 정형화된 느낌이다.

LIST

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

[C#]백준 17268번: 미팅의 저주  (0) 2023.09.25
[C#]백준 24511번: queuestack  (0) 2023.08.25
[C#]백준 16928번: 뱀과 사다리 게임  (0) 2023.08.25
[C#]백준 1149번: RGB거리  (0) 2023.08.25
[C#]백준 1912번: 연속합  (0) 2023.08.25
SMALL

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

 

2579번: 계단 오르기

계단 오르기 게임은 계단 아래 시작점부터 계단 꼭대기에 위치한 도착점까지 가는 게임이다. <그림 1>과 같이 각각의 계단에는 일정한 점수가 쓰여 있는데 계단을 밟으면 그 계단에 쓰여 있는 점

www.acmicpc.net


  • 문제풀이

동적계획법을 사용하여 계산해준다.

두가지의 경우로 나눌 수 있다.

 

1경우: 1칸, 2칸, 4칸(두칸 가고 한칸 건너띄기)

2경우: 1칸, 3칸(한칸 가고 한칸 건너띄기)


  • 코드 1
n = int(input())
stairs = [0] 
dp = [0] * (n + 1)

for _ in range(n):
    stairs.append(int(input()))

dp[1] = stairs[1]
if n >= 2:
    dp[2] = stairs[1] + stairs[2]

for i in range(3, n + 1):
    dp[i] = max(dp[i - 2] + stairs[i], dp[i - 3] + stairs[i - 1] + stairs[i])

print(dp[n])

 


  • 후기

동적계획법은 문제가 어느정도 정형화된 느낌이다.

LIST
SMALL

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

 

1931번: 회의실 배정

(1,4), (5,7), (8,11), (12,14) 를 이용할 수 있다.

www.acmicpc.net


  • 문제풀이

람다 값을 지정해서 집합에 넣고 빼준다.


  • 코드 1
N = int(input())
time_list = []
for i in range(N):
    Si, Fi = map(int, input().split())
    time_list.append((Si, Fi))

time_list.sort(key=lambda x: (x[1], x[0]))

count = 0
time = 0
for i in range(N):
    if time <= time_list[i][0]:
        count += 1
        time = time_list[i][1]

print(count)

 


  • 후기

파이썬을 연습하는 단계이다.

LIST
SMALL

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

 

7785번: 회사에 있는 사람

첫째 줄에 로그에 기록된 출입 기록의 수 n이 주어진다. (2 ≤ n ≤ 106) 다음 n개의 줄에는 출입 기록이 순서대로 주어지며, 각 사람의 이름이 주어지고 "enter"나 "leave"가 주어진다. "enter"인 경우는

www.acmicpc.net


  • 문제풀이

enter인 경우  집합에 넣고 leave인 경우 직원 명단에서 빼준다.


  • 코드 1
#-*- coding: utf-8 -*-

from collections import deque

n = int(input())  # 출입 기록의 개수

employees = set()  # 직원 명단을 저장할 집합(set) 생성

for _ in range(n):
    record = input().split()
    name, status = record[0], record[1]

    if status == "enter":
        employees.add(name)  # enter인 경우 직원 명단에 추가
    else:
        employees.remove(name)  # leave인 경우 직원 명단에서 제거

# 직원 명단을 알파벳 역순으로 정렬하여 출력
for employee in sorted(employees, reverse=True):
    print(employee)

 


  • 후기

파이썬을 연습하는 단계이다.

LIST
SMALL

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

 

24511번: queuestack

첫째 줄에 queuestack을 구성하는 자료구조의 개수 $N$이 주어진다. ($1 \leq N \leq 100\,000$) 둘째 줄에 길이 $N$의 수열 $A$가 주어진다. $i$번 자료구조가 큐라면 $A_i = 0$, 스택이라면 $A_i = 1$이다. 셋째 줄

www.acmicpc.net


  • 문제


  • 문제풀이

처음에는 문제에서 요구하는 그대로 작성했다가 시간초과가 발생했다.

using System;
using System.Collections.Generic;
using System.Text;

namespace QueueStackSimulation
{
    class Program
    {
        static void Main(string[] args)
        {
            int N = int.Parse(Console.ReadLine());
            int[] structureTypes = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);
            int[] structureData = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);

            List<Queue<int>> queues = new List<Queue<int>>();
            List<Stack<int>> stacks = new List<Stack<int>>();
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < N; i++)
            {
                if (structureTypes[i] == 0)
                {
                    Queue<int> queue = new Queue<int>();
                    queue.Enqueue(structureData[i]);
                    queues.Add(queue);
                }
                else
                {
                    Stack<int> stack = new Stack<int>();
                    stack.Push(structureData[i]);
                    stacks.Add(stack);
                }
            }

            int M = int.Parse(Console.ReadLine());
            int[] insertData = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);

            foreach (int data in insertData)
            {
                int result = -1; // Default value

                for (int i = 0; i < N; i++)
                {
                    if (queues.Count > i && queues[i].Count > 0)
                    {
                        result = queues[i].Dequeue();
                    }
                    else if (stacks.Count > i && stacks[i].Count > 0)
                    {
                        result = stacks[i].Pop();
                    }

                    if (result == data)
                    {
                        sb.Append(result + " ");
                        break;
                    }
                }
            }

            Console.WriteLine(sb.ToString().Trim());
        }
    }
}

 

스택은 처음 숫자가 그대로 남고 큐만 숫자가 변동 된다는 것을 알게 되었다. 따라서 스택은 무시하고 큐의 규에만 집중하여 코드를 짜면 해결할 수 있다.


  • 코드 1
using System;
using System.Collections.Generic;
using System.Text;

namespace CodeConversion
{
    class Program
    {
        static void Main(string[] args)
        {
            int N = int.Parse(Console.ReadLine());
            int[] sequence_A = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);
            int[] sequence_B = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);
            int M = int.Parse(Console.ReadLine());
            int[] sequence_C = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);
            StringBuilder sb = new StringBuilder();
            Queue<int> queue = new Queue<int>();
            for (int i = N - 1; i >= 0; i--)
            {
                if (sequence_A[i] == 0)
                {
                    queue.Enqueue(sequence_B[i]);
                }
            }



            for (int i = 0; i < M; i++)
            {
                queue.Enqueue(sequence_C[i]);
                sb.Append(queue.Dequeue() + " ");
            }
            Console.WriteLine(sb.ToString());

        }
    }
}

 


  • 후기

더 좋은 코드로 만들기 위해 손으로 직접해보는 것은 중요한 것 같다.

LIST

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

[C#]백준 17268번: 미팅의 저주  (0) 2023.09.25
[C#]백준 2579번: 계단 오르기  (0) 2023.09.25
[C#]백준 16928번: 뱀과 사다리 게임  (0) 2023.08.25
[C#]백준 1149번: RGB거리  (0) 2023.08.25
[C#]백준 1912번: 연속합  (0) 2023.08.25
SMALL

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

 

16928번: 뱀과 사다리 게임

첫째 줄에 게임판에 있는 사다리의 수 N(1 ≤ N ≤ 15)과 뱀의 수 M(1 ≤ M ≤ 15)이 주어진다. 둘째 줄부터 N개의 줄에는 사다리의 정보를 의미하는 x, y (x < y)가 주어진다. x번 칸에 도착하면, y번 칸으

www.acmicpc.net


  • 문제


  • 문제풀이

100칸짜리 맵을 만든 뒤 BFS방식을 사용하여 탐색을 한 후에 최소 횟수를 출력한다.

 


  • 코드 1
using System;
using System.Collections.Generic;
using System.Linq;

class SnakeAndLadderGame
{
    static void Main(string[] args)
    {
        List<int> ladderOrSnake = new List<int>(101);
        for (int i = 0; i <= 100; i++)
        {
            ladderOrSnake.Add(-1);
        }


        string[] input = Console.ReadLine().Split(' ');
        int N = int.Parse(input[0]);
        int M = int.Parse(input[1]);

        for (int i = 0; i < N + M; i++)
        {
            int[] data = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);

            if (data[0] < data[1])
            {
                ladderOrSnake[data[0]] = data[1];
            }
            else
            {
                ladderOrSnake[data[0]] = data[1];
            }
        }

        int[] dist = new int[101];
        for (int i = 0; i <= 100; i++)
        {
            dist[i] = -1;
        }
        dist[1] = 0;

        Queue<int> queue = new Queue<int>();
        queue.Enqueue(1);

        while (queue.Count > 0)
        {
            int curPos = queue.Dequeue();

            for (int i = 1; i <= 6; i++)
            {
                int nextPos = curPos + i;
                if (nextPos <= 100 && ladderOrSnake[nextPos] != -1)
                {
                    nextPos = ladderOrSnake[nextPos];
                }

                if (nextPos <= 100 && dist[nextPos] == -1)
                {
                    dist[nextPos] = dist[curPos] + 1;
                    queue.Enqueue(nextPos);
                }
            }
        }

        Console.WriteLine(dist[100]);
    }
}

 


  • 후기

그래프를 활용한 방식은 까먹지 않게 자주자주 해야겠다.

LIST

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

[C#]백준 2579번: 계단 오르기  (0) 2023.09.25
[C#]백준 24511번: queuestack  (0) 2023.08.25
[C#]백준 1149번: RGB거리  (0) 2023.08.25
[C#]백준 1912번: 연속합  (0) 2023.08.25
[C#]백준 11053번: 가장 긴 증가하는 부분 수열  (0) 2023.08.25

+ Recent posts