[BAEKJOON]4673番セルフサービス番号
4673番セルフサービス番号
質問:https://www.acmicpc.net/problem/4673
質問する
セルフサービス番号は1949年にインドの数学者D.R.Kaprekarによって命名された.正の整数nについて、d(n)がnおよびnの各ビット数の関数を定義する.例えば、d(75)=75+7+5=87である.
正の整数nが与えられると、その数からn、d(n)、d(d(n)、d(d(d(n))、...無限数列を生成できます.
たとえば、33で始まると、次の数字は33+3+3=39、次の数字は39+3+9=51、次の数字は51+5+1=57となります.このようにして、次の数の列を生成できます.
33, 39, 51, 57, 69, 84, 96, 111, 114, 120, 123, 129, 141, ...
nをd(n)の生成者と呼ぶ.上の数列において、33は39の生成者、39は51の生成者、51は57の生成者である.生成者が1つより多い場合もあります.例えば、101には2つの構造関数(91および100)がある.
生成されていない数字を自動番号と呼びます.100未満のセルフサービス番号は全部で13個です.1, 3, 5, 7, 9, 20, 31, 42, 53, 64, 75, 86, 97
10000以下のセルフ・サービス番号を出力するプログラムを作成します.
入力
入力していません.
しゅつりょく
10000以下の自己符号を行ごとに1つ追加する順序で出力します.
に答える
両者を比較する場合、この数字が
結果は予想通り、よく撮れました.出てきたけど…😮💨 演算時間を全く考慮していない無知な方法です.上記の状況を考慮すると、1から10000までの数字はd(n)を使用し、各d(n)も範囲に再呼び出され続けるため、長い時間がかかる.だから白俊もタイムアウトした.
数回の試みの結果,再帰関数を用いる必要はないと結論した.再帰関数を使用して1から範囲まで数値を繰り返すと、意味のない繰り返しが続きます.1から始まる数列(1,2,4,8,16...)の場合、2から始まる数列(2、4、8、16…)または4から始まる数列(4、8、16、...)との状況が繰り返されていることがわかります.一言でこのように和音を作ると叱られるよ.🥵
関数
最後に
この問題を解く過程で、時間の複雑さを考え始めました.上の2つのコードの時間差が明らかで、驚きました.初期コード付きのサービスが発売されたらどうなりますか?ユーザーのネガティブなフィードバックが殺到する可能性があります.機能の正常な動作だけでなく、効率とメモリの浪費を考慮したコードを作成する必要があります.
質問:https://www.acmicpc.net/problem/4673
質問する
セルフサービス番号は1949年にインドの数学者D.R.Kaprekarによって命名された.正の整数nについて、d(n)がnおよびnの各ビット数の関数を定義する.例えば、d(75)=75+7+5=87である.
正の整数nが与えられると、その数からn、d(n)、d(d(n)、d(d(d(n))、...無限数列を生成できます.
たとえば、33で始まると、次の数字は33+3+3=39、次の数字は39+3+9=51、次の数字は51+5+1=57となります.このようにして、次の数の列を生成できます.
33, 39, 51, 57, 69, 84, 96, 111, 114, 120, 123, 129, 141, ...
nをd(n)の生成者と呼ぶ.上の数列において、33は39の生成者、39は51の生成者、51は57の生成者である.生成者が1つより多い場合もあります.例えば、101には2つの構造関数(91および100)がある.
生成されていない数字を自動番号と呼びます.100未満のセルフサービス番号は全部で13個です.1, 3, 5, 7, 9, 20, 31, 42, 53, 64, 75, 86, 97
10000以下のセルフ・サービス番号を出力するプログラムを作成します.
入力
入力していません.
しゅつりょく
10000以下の自己符号を行ごとに1つ追加する順序で出力します.
に答える
let solResult = "";
// 원하는 범위까지 수열을 만드는 함수 d(n)
function d(n, limit, array) {
let N = String(n);
let result = Number(n);
if (result > limit) {
return;
}
for (let i = 0; i < N.length; i++) {
result += Number(N[i]);
}
array.push(result);
d(result, limit, array);
}
// 셀프넘버가 아닌 배열을 만들고 이를 1 ~ 범위까지의 배열과 비교
function solution(number) {
let array = [...Array(number)].map((a, i) => i + 1);
let noSelfNumber = [];
for (let i = 1; i < array.length; i++) {
d(i, array.length, noSelfNumber);
}
for (let i = 0; i < array.length; i++) {
if (noSelfNumber.indexOf(array[i]) === -1) {
solResult += array[i].toString();
solResult += "\n";
}
}
console.log(solResult);
}
solution(10000);
これは私が初めて考えた解題方法です.制限範囲への呼び出しを続行した後、まず、数列を生成するd(n)
関数が宣言され、1から範囲までの数値に対してd(n)
を実行することができる.結果をnoSelfNumber
という配列に入れ、1から範囲(10000)の配列と比較した.両者を比較する場合、この数字が
noSelfNumber
の配列になければ自動番号であるため、出力可能である.結果は予想通り、よく撮れました.出てきたけど…😮💨 演算時間を全く考慮していない無知な方法です.上記の状況を考慮すると、1から10000までの数字はd(n)を使用し、各d(n)も範囲に再呼び出され続けるため、長い時間がかかる.だから白俊もタイムアウトした.
数回の試みの結果,再帰関数を用いる必要はないと結論した.再帰関数を使用して1から範囲まで数値を繰り返すと、意味のない繰り返しが続きます.1から始まる数列(1,2,4,8,16...)の場合、2から始まる数列(2、4、8、16…)または4から始まる数列(4、8、16、...)との状況が繰り返されていることがわかります.一言でこのように和音を作ると叱られるよ.🥵
// 다시 작성한 코드
// 재귀를 없애고 한번만 실행되는 d(n) 함수를 선언
function d(n) {
let N = String(n);
let result = Number(n);
for (let i = 0; i < N.length; i++) {
result += Number(N[i]);
}
return result;
}
// d(n)의 결과는 셀프넘버가 아니므로 false를 넣음.
function solution(range) {
let selfNumber = [...Array(range)].map(() => true);
for (let i = 1; i < range; i++) {
selfNumber[d(i)] = false;
if (selfNumber[i]) {
console.log(i); // true인 index 출력
}
}
}
solution(10000);
上のコードはコミットされたコードを書き換えます.最初のコードよりも高速な演算速度を表示します.関数
d(n)
を宣言するとともに、再帰関数が削除される.いずれにしても1からd(n)
が実行されるため、再帰関数によって不要な重複要素を作成する必要はありません.solution()
の場合、selfNumber
配列を作成し、その値をtrue
にすべて入れます.その後、d(n)
関数を繰り返し文で呼び出し、結果値のindex
にfalse
を加えることで、自作番号ではない数字を区別することができる.最後に
true
値を有するindexを出力すると、所望の結果値が得られる.この問題を解く過程で、時間の複雑さを考え始めました.上の2つのコードの時間差が明らかで、驚きました.初期コード付きのサービスが発売されたらどうなりますか?ユーザーのネガティブなフィードバックが殺到する可能性があります.機能の正常な動作だけでなく、効率とメモリの浪費を考慮したコードを作成する必要があります.
Reference
この問題について([BAEKJOON]4673番セルフサービス番号), 我々は、より多くの情報をここで見つけました https://velog.io/@jun_n3/BAEKJOON-4673번-셀프넘버テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol