형 변환하기(4673)

이영준·2022년 4월 2일
0

#include <iostream>
#include <string>
using namespace std;

int d(int n) {
	int result = n;
	string newN = to_string(n);//정수에서 문자열로
	for (int i = 0; i < newN.size(); i++) {
		result += newN[i] - '0';
		/*result += (int)newN[i];*/
	}
	return result;

}

bool constructor(int n) {
	string newN = to_string(n);
	for (int i = n - newN.size() * 9; i <= n; i++) {
		if (d(i) == n)
			return true;
	}
	return false;
}


int main() {
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);
	int num;

	for (int i = 0; i <= 10000; i++) {
		if (!constructor(i)) {
			cout << i << "\n";
		}
	}
}

문제를 풀기위해 숫자의 각 자리값을 참조하고 싶었다.
사실 쓸데없이 어렵게 풀었지만 실상은 숫자를을 10으로 나누면서 나눌때마다의 나머지 값으로 접근하면 되는 거였다.

    int d(int n) {
        int result = n;
        string newN = to_string(n);//정수에서 문자열로
        for (int i = 0; i < newN.size(); i++) {
            result += newN[i] - '0';
            /*result += (int)newN[i];*/
        }
        return result;
    }

d 함수를 만들었다.
우선 자리값을 하나의 원소로 받기 위해 string으로 형변환을 했다.

정수 -> 문자열
to_string(int n)

그리고 배열의 원소 각각을 다시 숫자로 받아 원래의 숫자와 자리값을 더하는 계산을 해야 했는데,
string을 배열로 접근할 때 하나의 원소의 형은 string 이 아닌 char 였다.

string이었다면 stoi()함수를 이용했겠지만
char의 경우 단순 int로 변환한다면 아스키코드에 해당하는 char의 int값이 나와 원치않는 숫자를 얻을 수 있다.
따라서 널리 쓰이는 방법인

문자->정수
char i - '0'

로 아스키 코드표에서 숫자문자 ~ 숫자문자 간의 간격 자체가 문자형태의 원래 그 숫자와 같을 것이므로 위와같이 해준다.

    bool constructor(int n) {
        string newN = to_string(n);
        for (int i = n - newN.size() * 9; i <= n; i++) {
            if (d(i) == n)
                return true;
        }
        return false;
    }

다음은 d함수의 역인 생성자 함수를 만들었다. 사실 이미 10000까지 범위가 한정되어있는 문제이기 때문에 0~1000까지의 모든 d()를 체크하고 비어있는 부분을 생성자가 없는 것으로 받아 출력할 수도 있지만,
나는 생성자 존재 여부를 직접 구하는 함수를 만들었다. 어차피 d()를 했을 때 자신과 자릿수의 합이 출력된다면 각 자릿수가 최대 9이므로 자릿수 * 9 만큼만 최대로 커지는 것을 이용하여 d()를 확인하는 범위를 한정하였다.

profile
컴퓨터와 교육 그사이 어딘가

1개의 댓글

comment-user-thumbnail
2022년 4월 2일

내용이 정말 기대됩니다

답글 달기