https://www.acmicpc.net/problem/10807
1. 내가 푼 코드
문제점 :
굳이 int로 형변환해서 string[]배열을 int[] 로 만드는과정추가됨
System.Array라이브러리 함수몰라서 foreach문으로 타겟갚과 맞는지 판별
참고로 만약 배열을 형변환 할거면
여기서 for문으로 배열 형변환하면서 복사했는데
이렇게 말고
Array.ConvortAll( 변환할 배열, 변환할 형식 ) 사용!
string[] stringNumber = Console.ReadLine().Split();
int[] number = Array.ConvertAll(stringNumber, int.Parse);
https://coding-of-today.tistory.com/105
static void Main(string[] args)
{
int n = int.Parse(ReadLine());
int[] number = new int[n];
string[] s = new string[n];
s= ReadLine().Split();
int target = int.Parse(ReadLine());
for (int i = 0; i<n; i++)
{
number[i] = int.Parse(s[i]);
}
int count = 0;
foreach (int i in number)
{
if ( i == target)
{
count++;
}
}
WriteLine(count);
}
2. 다른사람 코드
(참고 https://velog.io/@ssu_hyun/%EB%B0%B1%EC%A4%80-C-%EA%B0%9C%EC%88%98-%EC%84%B8%EA%B8%B0-10807%EB%B2%88)
System.Array
// 해당조건을 만족하는 번호 반환, 없으면 -1
System.Array.FindIndex(배열, x => x.name == "A");
// 해당조건을 만족하는 첫번째 값 반환
System.Array.Find(배열, x => x.name == "A");
// 해당조건을 만족하는 모든 값 리스트로 반환
System.Array.FindAll(배열, x => x.name == "A");
// 중복만 추출
var redundantArray = System.Array.FindAll(배열, x => List.Contains(x));
// RemoveAll 용도
System.Array.FindAll(배열, x => x.name != "A");
// 해당조건을 만족하는 요소가 한 개라도 존재하는지 검사
System.Array.Exists(배열, x => x.name = "A");
// 내용물에 전부 1 더해 반환
int[] 배열 = System.Array.ConvertAll(배열, x => x+1);
// 0으로 초기화
int[] 배열 = System.Array.ConvertAll(배열, x => 0);
// true 검사
System.Array.Find(배열, x => x == true);
// true 검사2
System.Array.TrueForAll(배열, x => x.isOn == false);
// 포함 여부 검사
if (System.Array.TrueForAll(배열, x => List.Contains(x));
static void Main(string[] args)
{
// 정수의 개수
int n = int.Parse(Console.ReadLine());
// 정수 배열
string [] numbers = Console.ReadLine().Split();
// 찾으려는 정수
string v = Console.ReadLine();
//위의 foreach문이 Array.FindAll로 한줄로 정리됨
// 찾기
int result = Array.FindAll(numbers, x => x == v).Length;
Console.WriteLine(result);
}
3. 람다연습
static void Main(string[] args)
{
int num = int.Parse(Console.ReadLine());
string[] s = ReadLine().Split();
int target = int.Parse(Console.ReadLine());
var nums = s.Where(x => x == target.ToString());
WriteLine(nums.Count());
}
https://www.acmicpc.net/problem/10871
1. 푼 코드
반복되는 출력이기 때문에 StringBuilder 사용해서 성능 높이고
위 문제에서 배웠던 ConvertAll 형변환 적용시킴 => 한문장으로 string[] 을 int[]의 배열에 싹다형변환해서 넣어서 좋은듯
그런데 문제에서 요소의 개수를 명시적으로 입력받고 변수 n에 집어넣는데
foreach문에서는 변수 n을 아예 쓰지 않아
사용하려면 주석의 for문으로 쓰는게 맞는것 같긴하다
static void Main(string[] args)
{
StringBuilder stringBuilder = new StringBuilder();
string[] s = ReadLine().Split();
int n = int.Parse(s[0]);
int x = int.Parse(s[1]);
string[] num = ReadLine().Split();
int[] num_int = Array.ConvertAll(num, int.Parse);
foreach(int i in num_int)
{
if (i < x)
stringBuilder.Append(i.ToString() + " ");
}
/*for(int i = 0; i<n; i++)
{
if (num_int[i] < x)
stringBuilder.Append(num_int[i].ToString() + " ");
}
WriteLine(stringBuilder);*/
}
2. 다른사람코드
for문에서 형변환 수행
n과 x를 일일이 새로운 변수에 넣지않고 s[0], s[1]로 써서 코드자체는 짧긴한데.. 난 일단 지금은 내가 한 것 처럼 새로운 변수에 넣는게 좋다고 생각한다
static void Main(string[] args)
{
// s[0]은 수열의 A, s[1]은 정수 X
string[] s = ReadLine().Split();
// s[0]을 이루는 수열들
string[] q = ReadLine().Split();
StringBuilder answer = new StringBuilder();
for (int i = 0; i < int.Parse(s[0]); i++)
{
// 정수 x보다 작은 숫자들을 검출
if (int.Parse(s[1]) > int.Parse(q[i]))
{
// 해당 숫자들을 answer에 공백과 함께 추가한다.
answer.Append(q[i] + " ");
}
}
// 정답 출력
WriteLine(answer.ToString());
}
3. 람다연습
static void Main(string[] args)
{
string[] s = ReadLine().Split();
int length = int.Parse(s[0]);
int target = int.Parse(s[1]);
string[] arr = ReadLine().Split();
var result = arr.Where(x => int.Parse(x) < target);
foreach( var x in result)
{
Console.Write(x+ " ");
}
}
https://www.acmicpc.net/problem/10818
1. 내가 푼 코드
정말 단순하게 뭔가 배열의 최대 최소를 반환하는 라이브러리 함수가 있을 것 같아서 visual studio에 arr.하고 나오는 목록들에 Min()과 Max()를 사용했다
근데 원래는 ReadLine()을 for문 안에서 받았는데 이렇게 할 경우 런타임 에러가 나서 수정했다 (이유는 잘..)
수정 전
static void Main(string[] args)
{
int n = int.Parse(ReadLine());
int[] arr = new int[n];
for (int i =0; i < n; i++)
{
arr[i] = int.Parse(ReadLine());
}
WriteLine($"{arr.Min()} {arr.Max()}");
}
수정 후
static void Main(string[] args)
{
int n = int.Parse(ReadLine());
string[] s = ReadLine().Split();
int[] arr = new int[n];
for (int i =0; i < s.Length; i++)
{
arr[i] = int.Parse(s[i]);
}
WriteLine($"{arr.Min()} {arr.Max()}");
}
2. 이게 없다면 Sort는 있겠지 싶어 정렬해서 첫번째와 마지막 인덱스 출력하려 했는데 다른사람코드는 그렇게 풀으셨다
static void Main(string[] args)
{
// 입력 받음
int n = int.Parse(Console.ReadLine());
// 입력받은 숫자 길이만큼의 배열을 생성.
int[] arr = new int[n];
// 두번째로 입력받는 숫자들을 공백기준으로 잘라서 배열로 저장
string[] s = Console.ReadLine().Split();
// int로 바꿔서 저장
for (int i = 0; i < n; i++)
{
arr[i] = int.Parse(s[i]);
}
// 배열을 정렬
Array.Sort(arr);
// 배열의 맨앞과 맨뒤 출력
Console.WriteLine($"{arr[0]} {arr[n - 1]}");
}
https://www.acmicpc.net/problem/2562
1. 내가 푼 코드
..또 어찌어찌 맞긴 했는데 또 Max와 위에서 배운 System.Array의 FindIndex를 섞어 날먹(?) 했다..
static void Main(string[] args)
{
int[] arr = new int[9];
for(int i =0; i<arr.Length; i++)
{
arr[i] = int.Parse(ReadLine());
}
WriteLine(arr.Max());
WriteLine(Array.FindIndex(arr, x => x == arr.Max())+1);
}
2. 다른사람코드 세개 모두 동일한 방식
max 라는 비교값을 받는 변수를 설정해 for문으로 모든 인덱스를 비교하는 간단한 로직을 대체왜 생각못하고
날먹했을까...
static void Main(string[] args)
{
int[] arr = new int[9];
int max = 0;
int num = 0;
for(int i =0; i<arr.Length; i++)
{
arr[i] = int.Parse(ReadLine());
}
for(int i =0; i<arr.Length; i++)
{
if (arr[i] > max)
{
max = arr[i];
num = i + 1;
}
}
WriteLine($"{max}\n{num}");
}
https://www.acmicpc.net/problem/10810
static void Main(string[] args)
{
string[] s = ReadLine().Split();
int basketNum = int.Parse(s[0]);
int line = int.Parse(s[1]);
int[] baseket = new int[basketNum];
for (int i = 0; i < line; i++)
{
string[] s2 = ReadLine().Split();
for(int j = int.Parse(s2[0]) - 1; j<=int.Parse(s2[1]) - 1; j++)
{
baseket[j] = int.Parse(s2[2]);
}
}
foreach (int k in baseket)
{
Write(k+ " ");
}
}
https://www.acmicpc.net/problem/5597
1부터 30까지의 배열이 있을때 중간에 빈값이 2개가 있다. 이 2개의 값을 알아내고 싶을 때
틀렸으니 다시 풀어볼 것
check가왜 30이아니라 31?
check배열 사이즈가 31이긴해도 어짜피 인덱스 1부터 판별하니 check[0] 값이 판별대상에 있진 않음.
28번을 반복하여 입력받은수를 check의 인덱스번호로 사용하고, 입력받은 모든 배열의 값을 1로 만든다.
반복문을 통해 배열의 값이 1이 아닌 경우 해당 번호를 출력
- 30명의 과제 제출 여부 배열을 만든다.
- 제출한 학생의 출석번호를 입력 받는다.
- 출석번호에 해당하는 배열의 값을 1로 만든다.
- 반복문을 통해 앞 번호부터 배열의 값이 1이 아닌 경우 해당 번호를 출력한다.
static void Main(string[] args)
{
int[] check = new int[31];
for (int i = 0; i < 28; i++)
{
int n = int.Parse(ReadLine());
check[n] = 1;
}
for(int i =1; i<= 30; i++)
{
if (check[i] != 1)
{
WriteLine(i);
}
}
}
https://www.acmicpc.net/problem/3052
이것도 틀림......
이전문제도 그렇고 값을 배열의 요소로 활용하는법과,
bool형식의 배열을 활용하는 법을 좀 생각할 필요가 있다
방법 1. bool[] 배열 이용
어짜피 나머지는 0~41 로 나옴
42개의 요소를 가지는 bool배열을 만들고
나머지가 저장되어있는 arr[i]이 42번의 반복을 돌아 요소값에 해당하는 값과 일치하면,
그 값을 배열의 인덱스로활용해 true로 저장한다 ..
그러면 어짜피 나머지 2가 몇번나오든 isredundant[2] = true가 될 것이고
다시 isredundant[] 0~41까지의 반복문을 돌며 true값이면 count++를 한다
using System;
using System.Diagnostics.CodeAnalysis;
using System.Text;
using static System.Console;
namespace Baekjoon
{
class MainApp
{
static void Main(string[] args)
{
int[] arr = new int[10];
for(int i =0; i<arr.Length; i++)
{
arr[i] = int.Parse(ReadLine()) % 42;
}
bool[] isredundant = new bool[42];
for (int i =0; i<arr.Length; i++)
{
for(int j =0; j <42; j++)
{
if (arr[i] == j)
{
isredundant[j] = true;
}
}
}
int count = 0;
for(int i =0; i <42; i++)
{
// if(isredundant[i] ==true )와 같은의미!!
if(isredundant[i])
{
count++;
}
}
WriteLine(count);
}
}
}
이 코드를 더 줄이려면 이중포문을 사용하는것이 아니라,
그냥 위의 5597문제처럼
나머지값을 받은 뒤 그나머지값을 42사이즈를 가지는 bool배열의 인덱스 요소로 활용하여,
bool[나머지값] = true; 로해주고
포문으로 bool배열의 요소가 true면 count++. => 훨씬간결
static void Main(string[] args)
{
bool[] isredundant = new bool[42];
for(int i =0; i<10; i++)
{
int n = int.Parse(ReadLine()) % 42;
isredundant[n] = true;
}
int count= 0;
for(int i =0; i<isredundant.Length; i++)
{
if (isredundant[i])
{
count++;
}
}
Console.WriteLine(count);
}
다음방법을 얘기하전에
조금 쓸데없긴한데 아까
https://www.acmicpc.net/problem/5597 5597문제를 풀때도
제출한 학생번호를 인덱스로활용하여 arr[학생번호] = 1;
로 해줬는데,
bool[] 배열을 활용하면 1대신 true로 직관적이게 활용할 수 있겠네
static void Main(string[] args)
{
int[] num = new int[31];
bool[] isSubmit = new bool[31];
for(int i = 0; i < 28; i++)
{
int n = int.Parse(ReadLine());
isSubmit[n] = true;
}
for(int i =1; i < isSubmit.Length; i++)
{
if (isSubmit[i]==false)
{
Console.WriteLine(i);
}
}
}
https://www.acmicpc.net/problem/1546
이전 두문제에 비해 훨씬 간단했다
문제에 모든 과정이 나와있는 느낌이었다
코드를 실행했을 때 처음엔 scores[i] = scores[i]/highest * 100 연산을 거친 뒤 scores[i]가 최댓값 제외 (1) 0이 되는 문제가 있어 연산실수인가 했지만 int형식 배열이기 때문이었다.
이 문제는 오차를 10^-2 까지 허용해서 double 및 문자열 보간 : ### 출력방식을 사용하지 않고 float만으로 처리했다
알고리즘 문제이다보니 for문으로 가장 높은 점수와 형변환을 직접구현했지만
//<System.Array 사용>
/*scores = Array.ConvertAll(sinput, float.Parse);
Array.Sort(scores);
highest = scores[^1];*
실제 프로젝트 코딩할땐 위의 방법이 더 간편하니 알아만 두고, Convert.All은 저번에 알고도 생각이 안났으니 다시 상기시키자
static void Main(string[] args)
{
int n = Convert.ToInt32(Console.ReadLine());
string[] sinput = new string[n];
sinput = ReadLine().Split();
float[] scores = new float[n];
float highest=0;
//<System.Array 사용>
/*scores = Array.ConvertAll(sinput, float.Parse);
Array.Sort(scores);
highest = scores[^1];*/
//이 for문 대신 위의 함수 사용하면 간편
for(int i = 0; i< sinput.Length; i++)
{
scores[i] = float.Parse(sinput[i]);
if (scores[i] > highest ) highest = scores[i];
}
float sum = 0;
for (int i = 0; i < scores.Length; i++)
{
scores[i] = scores[i]/highest* 100;
sum += scores[i];
}
Console.WriteLine(sum / n);
}
https://www.acmicpc.net/status?user_id=zizh121&problem_id=8958&from_mine=1
몇번 연속되었는지 기억해둘 변수 combo와
점수를 저장할 scores만 있으면 된다
사실 문제에선 케이스 두개밖에없어서 = 'X' 조건이 아닌 else를 쓰는건 알지만 나중을 위한 느낌..? 으로 else if 사용
입력에 대해 고민하는것도 오래걸렸다
입력은 다음과 같은 방식이다
2
OXOXOXOX
OOXXOOXXOX
난 한줄마다의 요소를 어떻게든 배열에 집어넣을 생각만 하고 있었다.
for( int i =0; i< num; i++)
{
문자열 s = 여기서 ReadLine()받고
for( ....이제 이포문은 방금 입력받은 s만을 다룬다)
{
}
}
의 방법을 생각하지 못함.. 현타온다
조건식 오류도 오래걸렸는데
현재 s 는 문자열 배열이 아닌, 문자열이다.
그러면 문자열의 요소 s[i]를 가져오고 조건식을 사용할 때 난 if( s[i] == "O" ) 큰따음표로 쓰고 왜 안되는거지 하고 있었다..
문자열의 요소는 문자, 즉 Char형식이므로
큰따음표가 아닌 작은 따음표 ' ' 를 사용한다
if (s[i] == 'O')
static void Main(string[] args)
{
int num = int.Parse(ReadLine());
int scores = 0;
int combo = 0;
for(int i = 0; i < num; i++)
{
string s = ReadLine();
for(int j = 0; j<s.Length; j++)
{
if (s[j] == 'O')
{
combo++;
scores += combo;
}
else if (s[j] == 'X')
{
combo = 0;
}
}
WriteLine(scores);
scores = 0;
combo = 0;
}
}
https://www.acmicpc.net/problem/10811
1. 내가 푼 코드
변수가 많아 좀 지저분해보이긴 하지만 최선인 것 같다
이 문제는 다른 코드를 많이 찾지 못했지만 역순을 구현한 로직은 비슷한 것 같다
for문 대신 while문으로 while(i<j) 형식으로 하는 방법도 있다 (직접 해보진 않음)
기본적으로 임시 값을 저장할 변수 tem을 활용하여 값을 변환하는 어디서 많이 보던 기본로직을 활용했다
tem = a;
a = b;
b = tem;
실제로 <배열의 역순>을 구현하고 싶으면 이번처럼 직접구현해도 좋지만
System.Array의 Reverse()를 활용하자 (적용한 코드는 2번에)
static void Main(string[] args)
{
string[] input = ReadLine().Split();
int n = int.Parse(input[0]);
int m = int.Parse(input[1]);
int[] bascket = new int[n];
for(int i = 0; i < n; i++)
{
bascket[i] = i+1;
}
for (int q = 0; q<m; q++)
{
string[] ij = ReadLine().Split();
int i = int.Parse(ij[0]);
int j = int.Parse(ij[1]);
int tem;
for(int w = i-1; w <= j-1; w++)
{
tem = bascket[w];
bascket[w] = bascket[j - 1];
bascket[j - 1]= tem;
j--;
}
}
foreach(int i in bascket)
{
Console.Write($"{i} ");
}
}
2. System.Array.Revesre() 활용
매개변수를 살펴보면,
- 첫번째 목록에 역순으로 바꿀 대상인 배열이름,
- 두번째 목록에 순서를 바꿀 시작 인덱스(int),
- 세번째 목록에 범위를 지정해준다.(int)
정말 이 문제 자체인 Reverse()메소드 이다..
Array.Reverse(bascket, i - 1, j - i + 1);
적용해 볼 때 세번째 목록을 j-i로만 써서 출력이 다르게 나왔는데,
만약 인덱스 [0] 과 [1] 두개의 값을 서로 바꿔준다면 세번째 목록엔 1이 아닌, 2가 되어야 하므로
j - i + 1로 입력한다.
적용을 해보면 복잡하던 for문이 한줄로 끝난다 !
static void Main(string[] args)
{
string[] input = ReadLine().Split();
int n = int.Parse(input[0]);
int m = int.Parse(input[1]);
int[] bascket = new int[n];
for(int i = 0; i < n; i++)
{
bascket[i] = i+1;
}
for (int q = 0; q<m; q++)
{
string[] ij = ReadLine().Split();
int i = int.Parse(ij[0]);
int j = int.Parse(ij[1]);
Array.Reverse(bascket, i - 1, j - i + 1);
}
foreach (int i in bascket)
{
Console.Write(i + " ");
}
}