
문제 링크: https://www.acmicpc.net/problem/4673

10000 이하의 셀프 넘버를 찾는 것이기 때문에 상수 Max에 10000을 넣어준다.
bool[] 타입의 변수를 선언하고 Max 크기로 초기화한다. 이 변수는 앞으로 셀프 넘버가 아닌 수와 대응하는 위치의 값에 true를 넣어 구분해줄 것이다.
1~Max까지 for문을 돌려 셀프 넘버가 아닌 수들을 찾는다.
셀프넘버를 찾는 메소드는 for문으로 구현하는 방법, 재귀함수로 구현하는 방법이 있는데 나는 재귀함수로 구현했다.
문제에 나온대로 구현해준다.
18 -> 18 + 1 + 8 = 27 이 원리를 토대로 구현한다.
이제 다시 for문을 돌려 arr에 대응하는 위치의 값을 확인해 false면 셀프넘버이므로 출력한다.
using System;
using System.Text;
internal class Program
{
private static void Main()
{
StringBuilder result = new StringBuilder();
const int Max = 10000;
bool[] arr = new bool[Max];
for (int i = 1; i < Max; i++)
{
int number = Make(i);
if (number < Max)
{
arr[number] = true;
}
}
for (int i = 1; i < Max; i++)
{
if (!arr[i])
{
result.AppendLine(i.ToString());
}
}
Console.WriteLine(result.ToString());
}
private static int Make(int n) => Make(n, n);
private static int Make(int n, int sum) => n != 0 ? Make(n / 10, sum + (n % 10)) : sum;
}
다른 분들이 푼 소스를 보다가 파이썬으로 푼 것중에 괜찮은? 코드를 봐서 C#으로 다시 짜봤다.
그냥 숫자를 string으로 변환하고 풀었다. 물론 첫번째코드보다 실행시간은 더 길다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
internal class Program
{
private static void Main()
{
StringBuilder result = new StringBuilder();
const int Max = 10000;
var integers = Enumerable.Range(1, Max).ToList();
var notSelfNumbers = new Queue<int>();
foreach (var i in integers)
{
int sum = i;
foreach (var j in i.ToString())
{
sum += int.Parse(j.ToString());
}
notSelfNumbers.Enqueue(sum);
}
while (notSelfNumbers.Count != 0)
{
int n = notSelfNumbers.Dequeue();
integers.Remove(n);
}
foreach (var item in integers)
{
result.AppendLine(item.ToString());
}
Console.WriteLine(result.ToString());
}
}