전체 글 (162)
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:42:44

System.Linq(Language Intergrated Query) 네임스페이스에 속하는 

Distinct 메소드는 시퀀스에서 중복되는 요소를 제거해준다.

중복되는 요소 제거 후 반환을 IEnumerable<T> 타입으로 한다.

OrderBy 메소드는 인수로 람다 표현식을 받아 오름차순을 하고, 역시 반환을 IEnumerable<T>로 해준다.

반환된 IEnumerable<T> 형식은 리스트면 .ToList(),  배열이면 .ToArray()를 사용하면 다시 원래의 형식으로 돌려놓을 수 있다.

 

-람다 표현식?

람다 표현식 흔히 익명 함수라고 부르는데, 식별자 없이 사용 가능한게 특징이다.

예를들어 sArr = sArr.OrderBy(a => a.Length).ToArr(); 이 코드에서

(a => a.Length) 이 부분이 람다 표현식이다.

a는 OrderBy 메소드에 의해 sArr의 각 요소들을 참조하게 된다.

이 상태에서 => (람다 연산자) 에 의해 a의 길이가 구해지고,

구해진 길이를 토대로 오름차순 정렬이 수행된다.

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

[java] Getter / Setter  (0) 2024.05.31
[java] 접근 제한자  (0) 2024.05.31
[java] 패키지  (0) 2024.05.31
static에 관하여  (0) 2024.03.20
c#의 빠른 입출력  (0) 2024.03.20
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 21:03:46

static 키워드는 변수 / 메소드 / 클래스가 인스턴스에 귀속되지 않고, 클래스에 귀속되게 한다.

사용 시 '인스턴스이름.메소드이름() ' 이 아니라

'클래스이름.메소드이름()'  로 사용해야 한다.

 

c#을 구성하는 최소의 단위인 클래스는 메소드에서 인스턴스화 되어야 한다.

하지만 메소드는 클래스의 바깥에서 따로 존재 할 수 없기 때문에, 인스턴스를 생성하기 위해 인스턴스의 메소드를 사용해야 하는 역설적인 상황이 발생한다.

이럴때 인스턴스 생성 전에 메모리에 올라가는 static을 사용한다.

가장 자주 보는 예시가 바로 static void main(string[] args) - 메인 메소드이다.

참고로 c++의 경우는 함수가 클래스 바깥에서 존재할 수 있다고 하여 메인 '함수' 라고 한다.

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

[java] Getter / Setter  (0) 2024.05.31
[java] 접근 제한자  (0) 2024.05.31
[java] 패키지  (0) 2024.05.31
중복 요소 제거와 특정 키를 기준으로 오름차순 정렬하기  (0) 2024.03.20
c#의 빠른 입출력  (0) 2024.03.20
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