목록알고리즘 (226)
궤도
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/US0hA/btqKABHSsGA/NtQHxeBkeaht6RKyKhC4QK/img.png)
문제 풀이 약간 고민하다가 설마 이렇게 하면 될까 싶어서 얼레벌레 풀었는데 얼레벌레 풀렸다. 그래서 뭐라고 설명해야 할지는 잘 모르겠고, 아마 코드를 읽어보면 대충 이해될 것 같다. 소스코드 #define _CRT_SECURE_NO_WARNINGS #include char matrix[50][50]; char scan_matrix[250][250]; int main() { int R, C, ZR, ZC; char empty; scanf("%d %d %d %d", &R, &C, &ZR, &ZC); for (int i = 0; i < R; i++) { scanf("%c", &empty); for (int j = 0; j < C; j++) { scanf("%c", &matrix[i][j]); } } for (..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/kYw1Y/btqKv8HaCp2/5nFGeS1lQrKfHbPWUfhMW1/img.png)
문제 풀이 난 이렇게 도형이 나오고 소수점이 나오는 문제에 약하다. 진짜 약하단 뜻은 아니고, 그냥 하기 싫다는 뜻이다. 입력은 다음과 같다. 1. x1==0 2. y1==0 3. x1!=0 && y1!=0 그리고 아주 특별한 경우가 아니라면 저 커다란 삼각형은 삼각형 하나와 사각형 하나로 잘릴 것이다. 분명히 이상하게 생겼을 사각형의 넓이를 구하는건 의미없는 뻘짓일테니 삼각형의 넓이를 구하자. 대충 그림을 그려보면 알겠지만 1번의 경우엔 s1이 삼각형이고, 2번의 경우엔 s2가 삼각형이다. 대충 연필로 끄적이면서 식세우고 코드로 작성하자. 설마 x+y = 250이라는걸 모르는 사람은 없겠지? 3번의 경우라면 어떻게 해야할까? 이것도 대충 선분을 몇 개 그어보면 알 수 있다. x1이 125보다 크면 s1..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/uM79P/btqKxmYZ0j1/sz3vk8U4vNFskeTQwqXOZk/img.png)
문제 풀이 바라는게 참 많은 문제다. 일단 각 단어와 그 등장 횟수도 저장해야 하니 구조체를 사용한다. 단어들을 입력받으면서 등장 횟수를 0으로 초기화 한다. 단어 목록을 완성했으니, 첫 문자들도 first 배열에 저장한다. 등장 횟수가 같은 경우엔 사전순으로 단어를 선택한다고 했으니 배열에 들어온 단어들을 사전순으로 정렬한다. 그냥 삽입정렬을 단어 버전으로 적용했다. 혹시 모를 오류가 생길 수도 있으니까 그냥 맘편하게 strcpy와 strcmp를 썼다. printWord 함수에서 각 문자에 대해 출력할 단어를 선택한다. 일단 문자에 대해 출력될 수 있는 단어가 여러개일 수 있으니 문자와 단어의 첫 문자가 일치하는 모든 단어를 출력 후보 배열 flag에 넣는다. 모든 단어를 다 탐색한 뒤, 후보 배열에 ..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/b2EYUn/btqKxQyKeHf/cx6kr4cCgj6hAEgceDNwpK/img.png)
문제 풀이 동적계획법 문제의 수많은 유형 중 하나이다. 이런류의 문제를 처음 봤다면 어렵겠지만, 몇 개 풀어보고 나면 그 문제가 그 문제라 원활하게 풀 수 있다. 각 index에서의 최댓값을 m_max에 저장한다. 그럼 이제 m_max에 값이 어떻게 들어가는지 살펴보겠다. m_max[1] : 돈이 1개라면 그냥 그걸 주워가면 된다. 그러므로 m_max[1] = m[1] m_max[2] : 돈이 2개여도 그걸 다 주워간다 해서 규칙을 어기진 않는다. 그러므로 m_max[2] = m[1] + m[2] m_max[3] : 돈이 3개라면 이제 모든 돈을 주워갈 수는 없다. 3개 중 금액이 가장 커질 수 있는 2장을 가져가자. (근데 코드는 왜 [1]+[2]를 까먹었지? 실수한 것 같다.) m_max[n] (n>..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/bws3CB/btqKwrGrwov/kqkSdk1K9JEXo2uU31xkk1/img.png)
문제 풀이 너무 어렵게 생각해서 시간이 좀 걸렸다. 단순하게 생각하면 된다. 양끝을 서로 비교한다. 그럼 이 셋 중 하나일 것이다. 1. 양끝 숫자가 같다. 2. 왼쪽 숫자 오른쪽 숫자 1번의 경우라면 회문 조건을 충족하니 한칸씩 안으로 들어가면 된다. 2번의 경우라면 왼쪽 숫자가 커지도록 인접한 숫자와 더해주고, 3번의 경우라면 오른쪽 숫자가 커지도록 인접한 숫자와 더해준다. 재귀함수로 구현했는데, 반복문으로 구현해도 어려움은 없을 것 같다. 소스코드 #define _CRT_SECURE_NO_WARNINGS #include int cnt = 0; int arr[10]; void pal(int start, int end) { if (start == end || star..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/eKoPc4/btqKwRETqWY/8HHVM0KlPq8VyVDCCbTM6K/img.png)
문제 풀이 원소가 3개니까 원소가 {1개, 2개, 3개}인 부분 집합에 대해 각각 계산을 하면 된다. 원소가 3개라서 그냥 대충대충 작성했는데 원소가 이것보다 많아지면 백트래킹으로 원소를 뽑아서 계산하는 함수를 만들어야겠다. 평범하게 노가다 한 코드라 보는데 어려움은 없을 것이다. 소스코드 #include int main() { int arr[3]; int k, cnt = 0; for (int i = 0; i < 3; i++) scanf_s("%d", &arr[i]); scanf_s("%d", &k); for (int i = 0; i < 3; i++) { if (arr[i] == k) cnt++; } for (int i = 0; i < 2; i++) { for (int j = i + 1; j < 3; j..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/bgq0kS/btqKy6g1Ary/mpkvcquoonqTEYEnGQEDLk/img.png)
문제 풀이 뭐 이딴 문제가 있지 싶었던 문제였다. 문자열로 받는 척하지만 전부다 int로 바꿔서 쓰고 출력도 좀 깔끔하지 못하다. 세상에 이런 문제가 있을 수도 있다는걸 깨닫기 위해 적는다. 소스코드 #define _CRT_SECURE_NO_WARNINGS #include int main() { char input; int y[2], m[2], d[2]; int index = 0, back; char s; while (true) { scanf("%c", &input); if (index
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/blrTQJ/btqKuFyAI1t/bCVjk8FTt7SxS2GskLnVj1/img.png)
문제 풀이 반올림과 버림을 하는 문제이다. 그냥 원래 수에서 아래 2자리를 잘라두고, 잘라둔 수가 50이상이면 올려주고 아니면 그대로 두면 된다. 자릿수별로 숫자를 자르는 문제를 많이 풀었다면 어려움이 없을 것이다. 소스코드 #include int main() { int n; int arr[100]; scanf_s("%d", &n); for (int i = 0; i 4) printf("%d %d\n", arr[i] + 100, arr[i]); else ..