/ /プログラミング:アルゴリズム、数学、データ構造の10進表現で3を持つすべてのそのような数の数を与える

プログラミング:アルゴリズム、数学、データ構造の10進表現で3を持つすべてのそのような数の数を与える

数値nを指定すると、数字3を含まない1からnの数字を10進表現で返す関数を書く

この問題を解決する最も最適な方法は何か。

私は単純な、すなわちnlogn(複雑さを見てアプローチを推測するのは簡単:)で使用しているアプローチ)

回答:

回答№1は4

次のアルゴリズムは、10進表現では「3」のない0から(n-1)までの整数である。 (私は1 .. nから0 .. n-1までの間隔を次の計算をわずかに簡略化するために変更しました。)

(私は複雑さの計算の専門家ではないが、私はこのアルゴリズムの複雑さは O(log n)なぜなら、各桁ごとに固定数のステップを実行するからです n。)

第1の観察は、多くてもd桁の整数の数(すなわち、間隔0 .. 10の数字d-1)は10進数で3の数字を持たず、ちょうど9dなぜなら、各桁に9つの選択肢0,1,2,4,5,6,7,8,9があるからです。

ここで、5桁の数字n = a4a3a2a1a0.

私たちは間隔の小数表現で "3"を持たない整数の数を別々に計算します

  • 0:a4a3a2a1 0 <= i <a4a3a2a1a0
  • 1:a4a3a2 0 0 <= i <a4a3a2a1 0
  • 2:a4a3 0 0 0 <= i <a4a3a2 0 0
  • 3:a4 0 0 0 0 <= i <a4a3 0 0 0
  • 4:0 0 0 0 0 <= i <a4 0 0 0 0

区間Iにおける整数の数j 10進表記で「3」を持たない

  • 0の場合、上位の数値の1つがaj + 1、aj + 2、...は3に等しく、 さもないと:
  • aj * 9j、0 <= aの場合j <= 3、(aj の選択肢 jth 小数点以下桁すべてに対して9つの選択肢)、
  • (aj - 1)* 9j、aj> 3の場合(3はjの有効な選択肢ではないためth 数字)。

したがって、次のような機能があります。

/*
* Compute number of integers x with 0 <= x < n that do not
* have a 3 in their decimal representation.
*/
int f(int n)
{
int count = 0;
int a;      // The current digit a_j
int p = 1;  // The current value of 9^j

while (n > 0) {
a = n % 10;
if (a == 3) {
count = 0;
}
if (a <= 3) {
count += a * p;
} else {
count += (a-1) * p;
}
n /= 10;
p *= 9;
}

return count;
}