전체 글 (165)
2024-03-20 01:34:12

오늘 푼 문제 중 대부분이 입출력 시간을 맞추지 못해 시간 초과로 실패한 경우가 대부분이었다.

 

StringBuilder

StringBuilder는 불변성을 지니는 String 클래스의 단점을 보완하기 위해서 존재한다.

위에서 말했듯이 String 클래스는 불변하기에, 우리가 값을 수정할 때마다 저장공간에 새로운 공간을 받아서 해당 공간에 수정한 값을 집어넣는 방식으로 작동한다. (Reference값 변경)

즉 우리는 String의 값을 수정할 때마다 새로운 저장공간에 새로운 문자열을 '생성' 하고 있는 거다.

하지만 StringBuilder 는 내부적으로 값을 조합하고 삭제해서, 새로운 인스턴스 생성하지 않는다고 한다.

 

StreamReader / Writer

StreamReader와 Writer는 System.IO 네임스페이스에 속하는 클래스로 주로 파일 입출력에 사용된다고 한다.

StreamReader는 어떤 스트림(대표적으로 파일)을 읽어오고,

StreamWriter는 어떤 스트림을 쓴다.

 

OpenStandardInput / Output

간단하게 스트림을 열어주는 메소드다.

이를 통해 스트림을 읽어 들일 수 있거나, 내보낼 수 있다.

 

위의 StreamReader와 조합해서 사용한다.

ex) using var SR = new StreamReader(Console.OpenStandardInput());

      using var SW = new StreamWriter(Console.OpenStandardOutput());

     ...

     Arr[int.Parse(SR.ReadLine())];

     SW.WriteLine(Arr[i]);

'생각 두 접시' 카테고리의 다른 글

[java] Getter / Setter  (0) 2024.05.31
[java] 접근 제한자  (0) 2024.05.31
[java] 패키지  (0) 2024.05.31
중복 요소 제거와 특정 키를 기준으로 오름차순 정렬하기  (0) 2024.03.20
static에 관하여  (0) 2024.03.20
2024-03-20 00:54:35

첫째 줄에는 반복 횟수가, 둘째줄 부터는 입력이 주어진다.

괄호가 완전히 닫히게 되면 VPS라고 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using System.IO;
using System.Text;
 
namespace 연습장
{
    internal class Program
    {
        static void Main(string[] args)
        {
            int T = int.Parse(Console.ReadLine());
            
            for(int i = 0; i < T; i++)
            {
                int balance = 0;
                string PS = Console.ReadLine().Trim();
                for(int j = 0; j < PS.Length; j++)
                {
                    if (PS[j] == '(')
                        balance++;
                    else if (PS[j] == ')')
                        balance--;
                    if (balance < 0)
                        break;
                }
                if (balance == 0)
                    Console.WriteLine("YES");
                else
                    Console.WriteLine("NO");
            }
        }
    }
}
 
cs

 

'('와 ')'의 균형을 잡아줄 변수 하나를 만들고, '(' 라면 +1 //  ')' 라면 -1을 한다

'('의 수가 더 많은 경우에는 0이 아닌 양의 정수로 balance의 값이 나오기 때문에 NO(중요. 대문자임)

')'의 수가 더 많다면 루프에서 조건에 걸려서 나가게 된다.

마찬가지로 ')'로 시작한다면 절대로 VPS가 아니기 때문에 첫번째 루프에서 break된다.

2024-03-20 00:35:34

첫째 줄에 반복 횟수가, 둘째 줄부터 정렬할 정수가 한줄 씩 입력된다.

입력 횟수 자체는 10,000,000회로 무척 많지만, 입력되는 수는 최대 10,000 이므로 10,000칸의 배열을 만들고, 해당 배열을 한 칸씩 이동하며 0이 아닐때 1식 차감하며 해당 인덱스의 번호를 뱉는 식으로 짜면 될 것 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using System.Text;
 
namespace 연습장
{
    internal class Program
    {
        static void Main(string[] args)
        {
            int N = int.Parse(Console.ReadLine());
            int[] Arr = new int[10001];
 
            for (int i = 0; i < N; i++)
            {
                int input = int.Parse(Console.ReadLine());
                Arr[input]++;
            }
 
            for (int j = 1; j < Arr.Length; j++)
            {
                while (Arr[j] != 0)
                {
                    Arr[j]--;
                    Console.WriteLine(j);
                }
            }
        }
    }
}
 
cs

 

코드는 얼추 맞게 작성한 거 같은데 시간 초과라고 뜬다.

입력이 최대 10,000,000회 까지 주어지다 보니 그런 것 같다. 더 줄일 방법을 찾아야겠다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System.IO;
using System.Text;
 
namespace 연습장
{
    internal class Program
    {
        static void Main(string[] args)
        {
            StringBuilder sb = new StringBuilder();
            int N = int.Parse(Console.ReadLine());
            int[] Arr = new int[10001];
 
            for (int i = 0; i < N; i++)
            {
                int input = int.Parse(Console.ReadLine());
                Arr[input]++;
            }
 
            for (int j = 1; j < Arr.Length; j++)
            {
                while (Arr[j] != 0)
                {
                    Arr[j]--;
                    sb.Append(j + "\n");
                }
            }
            Console.WriteLine(sb);
        }
    }
}
cs

빠른 출력을 위해 오늘 배웠던 StringBuilder를 이용해 출력을 해보았는데, 용량이 초과되었다.

입력이 너무 커서 이 방법도 별로인 것 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System.IO;
using System.Text;
 
namespace 연습장
{
    internal class Program
    {
        static void Main(string[] args)
        {
            using var reader = new StreamReader(Console.OpenStandardInput());
            using var print = new StreamWriter(Console.OpenStandardOutput());
            int N = int.Parse(reader.ReadLine());
            int[] Arr = new int[10001];
 
            for (int i = 0; i < N; i++)
            {
                Arr[int.Parse(reader.ReadLine())]++;
            }
 
            for (int j = 1; j < Arr.Length; j++)
            {
                while (Arr[j] != 0)
                {
                    Arr[j]--;
                    print.WriteLine(j);
                }
            }
        }
    }
}
 
cs

찾아보니 입출력 속도를 높히는 방법이 몇개 더 있었다. 그 중 하나다 Stream(Reader/Writer)인데,

이 친구들은 특정한 스트림(데이터의 흐름을 추상화 한 것) 을 읽거나 쓴다.

또 OpenStandard(Input/Output)은 바이트 스트림을 열어서 프로그램으로 스트림이 들어오거나 나가게 해준다고 한다.

평소에 쓰던 ReadLine()과 WriteLine() 모두 이 OpenStandard(Input/Output)을 내장하고 있다고 한다.

 

'하루 한 접시' 카테고리의 다른 글

[백준] 11399번: ATM [C#]  (0) 2024.03.21
[백준] 1181번: 단어 정렬하기 [C#]  (0) 2024.03.20
[백준]9012번: 괄호 [C#]  (0) 2024.03.20
[백준]1920번: 수 찾기 [C#]  (0) 2024.03.19
[백준]2751번: 수 정렬하기 2 [C#]  (0) 2024.03.19
2024-03-19 23:39:37

첫째 줄에는 입력을 몇 개 받을 것인지(배열의 크기를 정함)

둘째 줄에는 입력이 문자열 형식으로 한 줄로 주어졌다.

셋째, 넷째 줄도 동일하게 주어진다.

정수는 최대 100,000개 가 주어질 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
 
using System.Text;
 
namespace 연습장
{
    internal class Program
    {
        static void Main(string[] args)
        {
            StringBuilder sb = new StringBuilder(); // 빠른 출력을 위한 StringBuild 클래스 선언
            int N = int.Parse(Console.ReadLine());
 
            string[] num = Console.ReadLine().Trim().Split();
            int[] numArr = new int[N];
 
            for (int i = 0; i < N; i++)
                numArr[i] = int.Parse(num[i]); // 이진 탐색을 위한 형 변환
           Array.Sort(numArr); // 이진 탐색을 위한 오름차순 정렬
 
            int M = int.Parse(Console.ReadLine());
 
            string[] search = Console.ReadLine().Trim().Split();
 
            for(int j = 0; j < M; j++)
            {
                int low = 0;
                int high = numArr.Length - 1;
                bool found = false;
                while(high >= low && !found)
                {
                    int mid = (low + high) / 2;
                    if (numArr[mid] == int.Parse(search[j]))
                    {
                        found = true;
                        break;
                    }
                    else if (numArr[mid] > int.Parse(search[j]))
                        high = mid - 1;
                    else low = mid + 1;
                }
                sb.Append(found ? "1\n" : "0\n"); // found 값에 따라 1과 0으로 sb에 넣음
            }
            Console.WriteLine(sb);
            
        }
    }
}
 
cs

첫번째 배열은 이진 탐색을 하기 위하여 int형으로 변환 후 오름차순으로 정렬했다.

이진 탐색으로 값을 찾아 sb(StringBuilder 인스턴스) 에 Append 후 출력해줬다.

역시 주어진 시간이 1초로 짧기 때문에 StringBuilder의 사용이 필수적인 것 같다.

2024-03-19 22:47:59

첫째 줄에 몇개를 입력 할 것인지 입력하고, 둘째부터 수를 정렬 할 수를 입력받는다.
입력된 수를 오름차순으로 정렬 한 후, 출력해주면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
using System.Text;
 
namespace 연습장
{
    internal class Program
    {
        static void Main(string[] args)
        {
            StringBuilder sb = new StringBuilder();
            int N = int.Parse(Console.ReadLine());
            int[] arr = new int[N];
 
            for(int i = 0; i < N; i++)
            {
                arr[i] = int.Parse(Console.ReadLine());
            }
            Array.Sort(arr);
 
            for(int j = 0; j < N; j++)
            {
                sb.Append(arr[j]+ "\n");
            }
            Console.WriteLine(sb);
        }
    }
}
 
cs

계속 시간 초과 오류가 나길래 왜 그런가 싶었는데, StringBuilder 클래스를 이용해서 출력하니 통과됐다.

아마 출력단계에서 큰 차이가 나는 것 같다.

 

'하루 한 접시' 카테고리의 다른 글

[백준] 11399번: ATM [C#]  (0) 2024.03.21
[백준] 1181번: 단어 정렬하기 [C#]  (0) 2024.03.20
[백준]9012번: 괄호 [C#]  (0) 2024.03.20
[백준]10989번: 수 정렬하기 3 [C#]  (0) 2024.03.20
[백준]1920번: 수 찾기 [C#]  (0) 2024.03.19