다시푸는 코딩 테스트 준비 일지
문제
N명이 모여 숫자 게임을 하고자 한다. 각 사람에게는 1부터 10사이의 수가 적혀진 다섯 장의 카드가 주어진다. 그 중 세 장의 카드를 골라 합을 구한 후 일의 자리 수가 가장 큰 사람이 게임을 이기게 된다. 세 장의 카드가 (7, 8, 10)인 경우에는 합은 7+8+10 = 25가 되고 일의 자리 수는 5가 된다. 어떤 사람이 받은 카드가 (7, 5, 5, 4, 9)인 경우 (7, 4, 9)를 선택하면 합이 20이 되어 일의 자리 수는 0이 되고, (5, 5, 9)를 선택하면 합이 19가 되어 일의 자리 수는 9가 된다. 게임을 이기기 위해서는 세 장의 카드를 선택할 때 그 합의 일의 자리 수가 가장 크게 되도록 선택하여야 한다.
예를 들어, N=3일 때
1번 사람이 (7, 5, 5, 4, 9),
2번 사람이 (1, 1, 1, 1, 1),
3번 사람이 (2, 3, 3, 2, 10)의
카드들을 받았을 경우, 세 수의 합에서 일의 자리 수가 가장 크게 되도록 세 수를 선택하면
1번 사람은 (5, 5, 9)에서 9,
2번 사람은 (1, 1, 1)에서 3,
3번 사람은 (2, 3, 3)에서 8의
결과를 각각 얻을 수 있으므로 첫 번째 사람이 이 게임을 이기게 된다.
N명에게 각각 다섯 장의 카드가 주어졌을 때, 세 장의 카드를 골라 합을 구한 후 일의 자리 수가 가장 큰 사람을 찾는 프로그램을 작성하시오. 가장 큰 수를 갖는 사람이 두 명 이상일 경우에는 번호가 가장 큰 사람의 번호를 출력한다.
입력
첫 줄에는 사람의 수를 나타내는 정수 N이 주어진다. N은 2이상 1,000이하이다. 그 다음 N 줄에는 1번부터 N번까지 각 사람이 가진 카드가 주어지는 데, 각 줄에는 1부터 10사이의 정수가 다섯 개씩 주어진다. 각 정수 사이에는 한 개의 빈칸이 있다.
출력
게임에서 이긴 사람의 번호를 첫 번째 줄에 출력한다. 이긴 사람이 두 명 이상일 경우에는 번호가 가장 큰 사람의 번호를 출력한다.
예제 입력 1 복사
3
7 5 5 4 9
1 1 1 1 1
2 3 3 2 10
예제 출력 1 복사
1
문제 풀이 접근
이 문제가 주어진 후, 바로 든 생각은 영락없이 조합 코드 사용해서 갱신해주면 되겠다. 였다.
정수형 2차원 배열인 int[][]로 입력을 구성했고, 사람수 만큼 루프 돌리면서 조합을 갱신하여 1의 자리 숫자가 제일 크면 갱신하고, 갱신되는 상황에서 if 문 한번 더 추가해서 현재 갱신된 사람의 번호보다 새롭게 들어온 사람의 번호가 크다면 갱신하는 방법으로 문제 풀이 방식을 설계했다.
작성 코드 (C#)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Net.NetworkInformation;
using static CodingTestProj.Program;
/*
* Difficulty :
* URL : https://www.acmicpc.net/problem/2303
* Time :
*/
namespace CodingTestProj
{
internal class Program
{
static void Main(string[] args)
{
var ss = new Solution();
ss.Solve();
}
}
public class Solution
{
public int n;
public List<int>[] _list;
int _lastNumb; // 일의 자리 숫자
int _ret;
public int[][] _arr;
public void Solve()
{
_ret = 0;
_lastNumb = 0;
int n = Int32.Parse(Console.ReadLine());
_arr = new int[n][];
for(int i = 0; i < n; ++i)
{
_arr[i] = new int[5];
}
for (int i = 0; i < n; i++)
{
string[] _input = Console.ReadLine().Split(' ');
for (int j= 0; j < _input.Length; ++j)
_arr[i][j] = int.Parse(_input[j]);
}
for(int i = 0; i < n; ++i)
{
int[] _c = new int[5];
combination(_arr[i], _c, 3, 0, 0, i+1);
}
print();
}
public void combination(int[] _arr, int[] _com, int r, int pos,int depth, int _person)
{
if (r == 0)
{
var _val1 = _com[0];
var _val2 = _com[1];
var _val3 = _com[2];
var ret = _val1 + _val2 + _val3;
// while (ret > 10) => 이 부분이 문제였다.
while (ret >= 10)
{
ret %= 10;
}
if (ret >= _lastNumb)
{
_lastNumb = ret;
if (_ret <= _person)
_ret = _person;
}
return;
}
else if (depth == _arr.Length)
return;
else
{
_com[pos] = _arr[depth];
combination(_arr, _com, r - 1, pos + 1, depth + 1, _person);
combination(_arr, _com, r, pos, depth + 1, _person);
}
}
public void print()
{
Console.WriteLine(_ret);
}
}
}
정답이라고 생각했고, 7%에서 틀렸는데 게시판에 있는 모든 반례는 통과하고 있어서 의문이다..
패스 한 후에 다시 포스팅할 예정이다.
=> 위에 while(ret > 10) 이 문제였다. 일의 자리수를 구하기 위해서는 10일때도 나눠서 0임을 뽑았어야했는데, 11부터 나누도록 해서 걸리는 케이스가 있었다.