結果
| 問題 |
No.2807 Have Another Go (Easy)
|
| コンテスト | |
| ユーザー |
navel_tos
|
| 提出日時 | 2024-07-12 22:29:55 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 118 ms / 3,000 ms |
| コード長 | 2,416 bytes |
| コンパイル時間 | 229 ms |
| コンパイル使用メモリ | 82,564 KB |
| 実行使用メモリ | 84,628 KB |
| 最終ジャッジ日時 | 2024-07-12 22:30:06 |
| 合計ジャッジ時間 | 5,859 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 46 |
ソースコード
#yukicoder 2807 Have Another Go(Easy)
#入力受取
N, M, K = map(int, input().split())
C = list(map(int, input().split()))
MOD = 998244353
#独立に問題を解く場合
def brute(N, M, Ci):
#DP[x][f]: 変数がx, Ci mod Nが出ていればf == 1となる場合の数
DP = [[0] * 2 for x in range(N * M + 1)]
DP[0][0] = 1
for x in range(N * M):
for k in range(1, 7): #次の目
y = x + k
if y >= N * M:
y = N * M
for f in range(2):
DP[y][f] += DP[x][f]
DP[y][f] %= MOD
else:
for f in range(2):
g = f
if y % N == Ci:
g = 1
DP[y][g] += DP[x][f]
DP[y][g] %= MOD
return DP[-1][-1]
#DPの前計算は必要
#DP[i]: マス0からマスiまでサイコロ移動をしたとき、「ちょうど」マスiに到達する場合の数
DP = [0] * (N * M + 6)
DP[0] = 1
for i in range(N * M):
for k in range(1, 7):
DP[i + k] += DP[i]
DP[i + k] %= MOD
#sub[i]: ゴールが6マス目のとき、iマス目から始めてゴールするまでの場合の数
sub = [0] * 6
for i in range(6):
dp = [0] * 7
dp[i] = 1
for j in range(6):
for k in range(1, 7):
dp[min(6, j + k)] += dp[j]
dp[min(6, j + k)] %= MOD
sub[i] = dp[-1]
del sub
#包除で解く
#Ciを踏んでゴール + (Ci + N)を踏んでゴール - (CiとCi + Nの両方)を踏んでゴール
def solve(N, M, Ci):
#1. Ciを踏んでから初期位置にワープし、2 * N - 6 ~ -1に再度移動する
cnt1 = DP[Ci]
cnt2 = 0
for i, j in enumerate(range(M * N - Ci - 6, M * N - Ci), start = 1):
cnt2 += DP[j] * i #i通りの出目でゴール可能
cnt2 %= MOD
ans = cnt1 * cnt2 % MOD
#2. N + Ciを踏んでから初期位置にワープ
#3. Ciを踏んでから初期位置にワープ、Nマス先のN + Ciをまた踏む(ダブルカウント)
cnt1 = DP[N + Ci] - (DP[Ci] * DP[N] % MOD)
cnt1 %= MOD
cnt2 = 0
for i, j in enumerate(range(N - Ci - 6, N - Ci), start = 1):
if j >= 0:
cnt2 += DP[j] * i
cnt2 %= MOD
ans += cnt1 * cnt2 % MOD
ans %= MOD
return ans
#答えを出力
for Ci in C:
print(solve(N, M, Ci))
navel_tos