あなたの最適化されたアプローチでは、数値ごとに桁の合計が1回だけ計算されるため、一見するとメモから得られるものはありません。
あなたは一つに二つのループをマージすることで、あなたのdiff
機能のパフォーマンスを向上させ、追加または数字を引くかどうかをルックアップするために辞書を使用することができます。
value = dict(zip("", (0, -1, 2, -3, 4,-5, 6,-7, 8,-9)))
def diff2(s):
s = str(s)
return abs(sum([value[i] for i in s]))
これは文字列への変換が必要になります。あなたは手で数字を計算することによって、少し速く(あまりない)を取得することができます:
dvalue = [0, -1, 2, -3, 4,-5, 6,-7, 8,-9]
def diff(s):
t = 0
while s:
t += dvalue[s % 10]
s //= 10
return abs(t)
最後に、あなたは2&middotまでの2からすべての桁の合計を計算しているという事実を利用することができます;順次n個。現在の数値の桁を配列に格納し、オドメータのようなカウンタを実装します。そのカウンタをインクリメントするときは、奇数と偶数の合計を追跡します。 10件のうち9件では、それぞれの合計からその値を削除し、次の桁を他の合計に加算するだけで、最後の桁を調整する必要があります。
これはこれを行うプログラムです。関数next
は、カウンタをインクリメントし、偶数と奇数の桁の合計をsums[0]
とsums[1]
に保持します。メインプログラムは、ループが2つに分割されていることを除いて、基本的にあなたと同じです:1つは、k
が増加し、1が減少する場所です。
even = set(range(0, 10, 2))
def next(num, sums):
o = num[0]
if o in even:
sums[0] -= o
sums[1] += o + 1
else:
sums[0] += o + 1
sums[1] -= o
num[0] += 1
i = 0
while num[i] == 10:
sums[0] -= 10
num[i] = 0
i += 1
o = num[i]
if o in even:
sums[0] -= o
sums[1] += o + 1
else:
sums[0] += o + 1
sums[1] -= o
num[i] += 1
n = int(raw_input())
total = 0
m = len(str(2 * n + 1))
num = [0] * m
num[0] = 2
sums = [2, 0]
k = 1
for i in range(2, n + 2):
total += abs(sums[0] - sums[1]) * k
k += 1
next(num, sums)
k = n
for i in range(n + 2, 2*n + 1):
k -= 1
total += abs(sums[0] - sums[1]) * k
next(num, sums)
print total
上記のメモは、このアプローチには役立ちません。それは真実ではない。番号i
の偶数と奇数の桁の合計を格納し、数字10 * i
〜10 * i + 9
を計算するときにそれを使用することができます。 diff
をi
の順に呼び出すと、保存された合計額はi // 10
になります。
これはオドメーターのアプローチよりも格段に高速ではありませんが、実装がより多くのメモリを犠牲にしてより明確になります。 (事前に割り当てられた配列は、大きな文字の辞書よりも優れていますn
)。あなたは(2*n + 11)/10
上記の数値のためのスペースを確保する必要はありません。)
def diff(s):
d = s % 10
e = ememo[s/10]
o = omemo[s/10]
if d in even:
e += d
else:
o += d
if s < smax:
ememo[s] = e
omemo[s] = o
return e, o
n = int(raw_input())
total = 0
even = set(range(0, 10, 2))
smax = (2*n + 11)/10
omemo = smax * [0]
ememo = smax * [0]
omemo[1] = 1
k = 1
for i in range(2, n + 2):
e, o = diff(i)
total += abs(e - o) * k
k += 1
k = n
for i in range(n + 2, 2*n + 1):
k -= 1
e, o = diff(i)
total += abs(e - o) * k
print total
1の桁の合計のためのクローズド式を見つけることができる場合、これはより速く作ることができるが、私は絶対的な機能は、このような解決策を防止することを考えます。
thanx btwしかし、あなたが言っていた数式を計算することで、より良い結果が得られます。 –
@bosey:閉形式で解くことができれば、それはもちろん最も効率的です。しかし、私はそのような公式は見つけられませんでした。私は 'sum(| odd-even |) 'の絶対関数がそのような公式を見つけるのを難しくしていると思います。 –