본문 바로가기
프로그래밍/Algorithm

C# [백준 BAEKJOON] 15649번 N과 M (1)

by bantomak 2024. 3. 6.

문제

자연수 N과 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.

  • 1부터 N까지 자연수 중에서 중복 없이 M개를 고른 수열

 

입력

첫째 줄에 자연수 N과 M이 주어진다. (1 ≤ M ≤ N ≤ 8)

 

출력

한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다.

수열은 사전 순으로 증가하는 순서로 출력해야 한다.

 

 

15649번: N과 M (1)

한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다. 수열은 사전 순으로 증가하는 순서로 출력해

www.acmicpc.net

 

재귀로 구현한 순열

using System;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        var input = Console.ReadLine().Split();
        var value1 = Int32.Parse(input[0]);
        var value2 = Int32.Parse(input[1]);

        var ints = Enumerable.Range(1, value1).ToArray();

        Combination(ints, 0, ints.Length, value2);
    }

    static void Combination(int[] array, int depth, int n, int k)
    {
        if (depth == k)
        {
            for (int i = 0; i < k; i++) 
            {
                Console.Write(array[i] + " ");
            }

            Console.WriteLine();
        }

        for (int i = depth; i < n; i++)
        {
            Swap(array, i, depth);
            Combination(array, depth + 1, n, k);
            Swap(array, i, depth);
        }
    }

    static void Swap(int[] array, int a, int b)
    {
        var temp = array[a];
        array[a] = array[b];
        array[b] = temp;
    }
}

 

DFS로 구현한 코드(하지만 제출시 시간 초과)

using System;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        var input = Console.ReadLine().Split();
        var value1 = Int32.Parse(input[0]);
        var value2 = Int32.Parse(input[1]);

        var ints = Enumerable.Range(0, value1).ToArray();
        var bools = Enumerable.Repeat(false, value1).ToArray();

        Combination_DFS(ints, bools, 0, ints.Length, value2);
    }

    static void Combination_DFS(int[] array, bool[] visit, int depth, int n, int r)
    {
        if (depth == r)
        {
            for (int i = 0; i < r; i++)
            {
                Console.Write($"{array[i]} ");
            }

            Console.WriteLine();
        }

        for (int i = 0; i < n; i++)
        {
            if (visit[i]) continue;

            visit[i] = true;
            array[depth] = i + 1;
            Combination_DFS(array, visit, depth + 1, n, r);
            visit[i] = false;
        }
    }
}

 

DFS로 구현한 코드

StreamWriter로 출력하니깐 시간 초과에 걸리고 제출이 성공하였다. 이유는 이제부터 알아보도록 하자.

 

using System;
using System.IO;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        StreamWriter writer = new StreamWriter(Console.OpenStandardOutput());
        StreamReader reader = new StreamReader(Console.OpenStandardInput());

        var input = reader.ReadLine().Split();
        var value1 = Int32.Parse(input[0]);
        var value2 = Int32.Parse(input[1]);

        var ints = Enumerable.Range(0, value1).ToArray();
        var bools = Enumerable.Repeat(false, value1).ToArray();

        Combination_DFS(writer, ints, bools, 0, value1, value2);

        writer.Close();
        reader.Close();
    }

    static void Combination_DFS(StreamWriter writer, int[] array, bool[] visit, int depth, int n, int r)
    {
        if (depth == r)
        {
            for (int i = 0; i < r; i++)
            {
                writer.Write($"{array[i]} ");
            }

            writer.WriteLine();
        }

        for (int i = 0; i < n; i++)
        {
            if (visit[i]) continue;

            visit[i] = true;
            array[depth] = i + 1;
            Combination_DFS(writer, array, visit, depth + 1, n, r);
            visit[i] = false;
        }
    }
}

 

참고 사이트

 

[백준 - C#] 15649번 N과 M (1)

문제링크 https://www.acmicpc.net/problem/15649 15649번: N과 M (1) 한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력

bokhead.tistory.com

댓글