하루 한 접시 (60)
2024-03-22 00:09:58

첫번째 줄에 띄어쓰기 없이 숫자가 주어진다.

주어진 수를 오름차순 정렬이 아닌, 내림차순 정렬을 해서 띄어쓰기 없이 한 줄로 출력하면 된다.

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
using System.IO;
using System.Text;
using System.Linq;
using System.Reflection.PortableExecutable;
 
namespace 연습장
{
    internal class Program
    {
        static void Main(string[] args)
        {
            using var reader = new StreamReader(Console.OpenStandardInput());
            using var print = new StreamWriter(Console.OpenStandardOutput());
            StringBuilder sb = new StringBuilder();
 
            string str = reader.ReadLine();
            int[] Dec = new int[str.Length];
 
 
            for(int i = 0; i < str.Length; i++)
            {
                Dec[i] = str[i] - '0';
            }
 
            for(int j=0; j<Dec.Length; j++)
            {
                int temp = 0;
                for(int k=j; k<Dec.Length; k++)
                {
                    if (Dec[j] < Dec[k])
                    {
                        temp = Dec[k];
                        Dec[k] = Dec[j];
                        Dec[j] = temp;
                    }
                }
            }
            foreach (int a in Dec)
                sb.Append(a);
 
            print.Write(sb);
 
        }
    }
}
cs

이번 문제는 내림차순을 구현하는 문제이다.

비록 Array.sort(Dec); Array.Reverse(Dec); 혹은

Dec = Dec.OrderByDesCending(x => x).ToArray(); 메소드를 사용해서 구현할 수 있겠지만,

이번 문제의 핵심은 지금까지는 오름차순을 사용했겠지만 이번엔 "직접 내림차순을 구현해 봐라"

라는 의미로 와닿아서 직접 구현을 해봤다.

2024-03-21 23:43:42

숫자 5개를 한줄 씩 입력받아 정렬하고, 중앙값과 평균값을 구하면 되는 아주 쉬운 문제.

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
using System.IO;
using System.Text;
using System.Linq;
using System.Reflection.PortableExecutable;
 
namespace 연습장
{
    internal class Program
    {
        static void Main(string[] args)
        {
            int[] num = new int[5];
            int mid;
            int avg = 0;
            
            for (int i = 0; i < 5; i++)
            {
                num[i] = int.Parse(Console.ReadLine());
                avg += num[i];
            } avg /= 5;
            Array.Sort(num);
            mid = num[2];
            Console.WriteLine(avg);
            Console.WriteLine(mid);
        }
    }
}
cs

2024-03-21 23:39:19

정수 세개가 한 줄에 입력되고, 그걸 정렬해서 2번째 원소를 출력해주면 되는 간단한 문제이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using System.IO;
using System.Text;
using System.Linq;
using System.Reflection.PortableExecutable;
 
namespace 연습장
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string[] arr = Console.ReadLine().Split();
            int[] num = new int[arr.Length];
 
            for (int i = 0; i < arr.Length; i++)
                num[i] = int.Parse(arr[i]);
 
            Array.Sort(num);
 
            Console.WriteLine(num[1]);
        }
    }
}
cs

 

 

2024-03-21 23:34:52

첫째 줄에 반복 횟수가, 둘째 줄부터 x좌표와 y좌표가 한줄로 주어진다.

문제에서 요구한는 출력은 x좌표를 기준으로 오름차순 정렬을 한 후, y좌표를 기준으로 오름차순 정렬을 해주면 된다.

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
using System.IO;
using System.Text;
using System.Linq;
using System.Reflection.PortableExecutable;
 
namespace 연습장
{
    internal class Program
    {
        static void Main(string[] args)
        {
            using var reader = new StreamReader(Console.OpenStandardInput());
            using var print = new StreamWriter(Console.OpenStandardOutput());
            StringBuilder sb = new StringBuilder();
            List<Tuple<intint>> list = new List<Tuple<intint>>();
 
            int N = int.Parse(reader.ReadLine());
 
            for (int i = 0; i < N; i++)
            {
                string[] str = reader.ReadLine().Split();
                list.Add(new Tuple<intint>(int.Parse(str[0]), int.Parse(str[1])));
            }
            list.Sort();
 
            foreach (Tuple<intint> a in list)
                sb.Append((a.Item1) + " " + (a.Item2) + "\n");
 
            print.WriteLine(sb);
 
 
        }
    }
}
cs

리스트를 튜틀타입으로 x, y좌표를 입력받아, 내장 메서드인 sort를 사용해 정렬 해준 뒤 출력했습니다.

주어진 시간이 1초라는 짧은 시간이기 때문에, 일반적인 방법으로 입/출력을 했을 때 시간 초과로 틀렸다고 떴었네요.

그래서 StringBuilder를 사용했더니 아슬아슬 하지만 통과는 했습니다.

그리고 StreamReader / StreamWriter 까지 써주니 작동 시간이 거의 절반으로 줄어들며 드라마틱한 시간 단축 효과를 얻었네요.

이정도면 단순 입출력 문제가 아닌 이상 거의 항상 사용해야 할듯.

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

[백준] 2587번: 대표값2 [C#]  (0) 2024.03.21
[백준] 10817번: 세 수[C#]  (0) 2024.03.21
[백준] 11399번: ATM [C#]  (0) 2024.03.21
[백준] 1181번: 단어 정렬하기 [C#]  (0) 2024.03.20
[백준]9012번: 괄호 [C#]  (0) 2024.03.20
2024-03-21 00:30:22

첫째 줄에 몇명이 돈을 인출하러 왔는지, 둘째 줄에 돈을 인출하는데 각각 몇분 씩 걸리는지가 한 줄로 입력된다.

각종 기호를 통해 착각이 들 수 있겠으나, 우리에게 중요한 건 오직 모두가 인출한는데 걸리는 '최단 시간' 이므로 int형 배열에 시간만 넣은 후 오름차순 정렬하여 총 인출 시간을 구하면 된다

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
using System.IO;
using System.Text;
using System.Linq;
using System.Reflection.PortableExecutable;
 
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 tot = 0int cnt = 0;
 
            string[] str = reader.ReadLine().Split();
            int[] num = new int[N];
 
            for(int i=0; i<N; i++)
            {
                num[i] = int.Parse(str[i]);
            }
            Array.Sort(num);
 
            for(int j = 0; j < N; j++)
            {
                for(int k = 0; k <= cnt; k++ )
                {
                    tot += num[k];
                } cnt++;
            }
            print.WriteLine(tot);            
 
        }
    }
}
cs

이렇게나 간단한 문제인데, 인덱스 번호도 고려할라고 이차원 배열이니 튜플 리스트니 끙끙대다가 시간만 신경쓰면 된다는걸 깨닫고는 너무 허무했다. 다음부터는 문제를 꼼꼼히 읽어, 문제가 요구하는 사항에 맞춰 코딩을 해야겠다.

그리고 그리디 알고리즘 관련 문제라는데... 아직 배우지 못한 부분이라 얼렁뚱땅 넘어간거 같아서 좀 그렇다...

2024-03-20 22:16:51

첫째 줄에는 반복 횟수. 둘째 줄부터는 단어가 입력된다.

단어는 중복을 제외해야 한다.

정렬은 1. 길이가 짧은 순서 -> 2. 알파벳 사전 순서대로 해야 한다.

----------------------------------------------------------------------------------------------------------------------------------------------------------------

정렬은 순서를 거꾸로 뒤집어 알파벳 사전 순 정렬(문자열 정렬)을 먼저하고,

길이순 정렬( int 정렬)을 해주면 된다. 

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
using System.IO;
using System.Text;
//using System.Linq;
 
namespace 연습장
{
    internal class Program
    {
        static void Main(string[] args)
        {
            using var reader = new StreamReader(Console.OpenStandardInput());
            using var print = new StreamWriter(Console.OpenStandardOutput());
            StringBuilder sb = new StringBuilder();
 
            int N = int.Parse(reader.ReadLine());
            string[] sArr = new string[N];
 
            for(int i = 0; i < N; i++)
            {
                sArr[i] = reader.ReadLine().ToLower();
            }
 
            sArr = sArr.Distinct().ToArray();
            Array.Sort(sArr);
            sArr = sArr.OrderBy(a => a.Length).ToArray();
 
            foreach (string res in sArr)
                sb.Append(res + "\n");
 
            print.WriteLine(sb);
 
        }
    }
}
cs

처음에는 중복 문자열을 제거하는 메소드와 문자열을 길이 순서대로 정렬해주는 메소드를 몰라서 직접 구현을 했었는데,

계속 틀렸다.

 

.Distinct() 메소드는 리스트 혹은 배열에서 중복되는 값들을 제거 한 후 IEnumerable 요소들을 반환한다고 한다. ToList() 혹은 ToArray를 통해 원래의 형태로 변환시킬 수 있다고 한다.

.OrderBy 메소드는  람다 표현식을 인수로 받아 오름차순 정렬을 한 후 IEnumerable 로 반환한다고 한다.

이 두 메소드는 모두 System.Linq 네임스페이스에 속하기 때문에, using System.Linq를 적어 줘야 한다.

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

[백준] 11650번: 좌표 정렬하기 [C#]  (0) 2024.03.21
[백준] 11399번: ATM [C#]  (0) 2024.03.21
[백준]9012번: 괄호 [C#]  (0) 2024.03.20
[백준]10989번: 수 정렬하기 3 [C#]  (0) 2024.03.20
[백준]1920번: 수 찾기 [C#]  (0) 2024.03.19
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