結果
| 問題 |
No.3136 F,B in FizzBuzzString16
|
| コンテスト | |
| ユーザー |
ID 21712
|
| 提出日時 | 2025-04-28 17:40:44 |
| 言語 | Python3 (3.13.1 + numpy 2.2.1 + scipy 1.14.1) |
| 結果 |
AC
|
| 実行時間 | 90 ms / 2,000 ms |
| コード長 | 3,396 bytes |
| コンパイル時間 | 672 ms |
| コンパイル使用メモリ | 12,672 KB |
| 実行使用メモリ | 11,008 KB |
| 最終ジャッジ日時 | 2025-04-28 17:40:50 |
| 合計ジャッジ時間 | 5,008 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 7 |
| other | AC * 32 |
ソースコード
#!/bin/python3
# F,B in FizzBuzzString16
# author: Leonardone @ NEETSDKASU
def FizzBuzz16(i):
if i % 15 == 0:
return "FizzBuzz"
elif i % 3 == 0:
return "Fizz"
elif i % 5 == 0:
return "Buzz"
else:
return "%X" % i
# FizzBuzzString16(v)のFとBの個数の合計を求める
def CountFBofFizzBuzzString16(v):
if v < 1:
return 0
# 桁の組み合わせの総数
# DP[桁数][桁の和][F,Bの個数]
DP = [[[0]*11 for _b in range(150+16)] for _a in range(10)]
# DPの初期値の設定
b = 0
c = 0
for a in range(10):
d = int(("%010X" % v)[a], 16)
for t in range(d):
if t == 0xB:
DP[a][b+t][c+1] += 1
else:
DP[a][b+t][c] += 1
if d == 0xF or d == 0xB:
c += 1
b += d
DP[9][b][c] += 1
for a in range(9):
for b in range(150):
for c in range(10):
for d in range(0x10):
if d == 0xF or d == 0xB:
DP[a+1][b+d][c+1] += DP[a][b][c]
else:
DP[a+1][b+d][c] += DP[a][b][c]
count = 0
for b in range(1,150):
for c in range(11):
if b % 15 == 0:
count += 2 * DP[9][b][c]
elif b % 3 == 0:
count += DP[9][b][c]
elif b % 5 == 0:
count += DP[9][b][c]
else:
count += c * DP[9][b][c]
return count
# FizzBuzzString16(v)の文字列長を求める
def FizzBuzzString16Length(v):
if v < 1:
return 0
length = 0
digit_size = 1
while True:
lower = pow(16, digit_size-1)
if lower > v:
return length
upper = min(v, lower*16-1)
count15 = (upper // 15) - ((lower-1) // 15)
count3 = (upper // 3) - ((lower-1) // 3)
count5 = (upper // 5) - ((lower-1) // 5)
count = upper - (lower-1)
fizzbuzz = 8 * count15
fizz = 4 * (count3 - count15)
buzz = 4 * (count5 - count15)
hex_number = digit_size * (count - (count3 + count5 - count15))
length += fizzbuzz + fizz + buzz + hex_number
digit_size += 1
# FizzBuzzString16(1000000000000)のv文字目において
# FizzBuzzString16Length(N - 1) < v <= FizzBuzzString16Length(N)
# となるNを求める
def FindNfromPosition(v):
lower = 0
upper = 1000000000001
while lower + 1 < upper:
middle = (lower + upper) // 2
count = FizzBuzzString16Length(middle)
if count < v:
lower = middle
else:
upper = middle
return upper
# FizzBuzzString16(1000000000000)の1文字目からv文字目までのFとBの個数の合計を求める
def CountFBtoPosition(v):
if v < 1:
return 0
N = FindNfromPosition(v)
count = CountFBofFizzBuzzString16(N - 1)
length = v - FizzBuzzString16Length(N - 1)
for ch in FizzBuzz16(N)[:length]:
if ch == 'F' or ch == 'B':
count += 1
return count
def solve(X, Y):
a = CountFBtoPosition(Y)
b = CountFBtoPosition(X - 1)
answer = a - b
return answer
if __name__ == '__main__':
X = int(input().strip())
Y = int(input().strip())
ans = solve(X,Y)
print(ans)
ID 21712