結果
| 問題 |
No.361 門松ゲーム2
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2023-02-21 17:13:50 |
| 言語 | Go (1.23.4) |
| 結果 |
AC
|
| 実行時間 | 170 ms / 2,000 ms |
| コード長 | 1,563 bytes |
| コンパイル時間 | 13,214 ms |
| コンパイル使用メモリ | 224,156 KB |
| 実行使用メモリ | 6,812 KB |
| 最終ジャッジ日時 | 2024-07-22 03:35:19 |
| 合計ジャッジ時間 | 14,614 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 28 |
ソースコード
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
// !分割竹子
// 有一根长L的竹子,轮流分成三段,要保证L1,L2,L3都不相等长且不为0
// 且 max(L1,L2,L3)-min(L1,L2,L3)<=D
// 不能继续操作的人输
// 问先手是否必胜
// 1<=D<=L<=500
in := bufio.NewReader(os.Stdin)
out := bufio.NewWriter(os.Stdout)
defer out.Flush()
var L, D int
fmt.Fscan(in, &L, &D)
memo := make([]int, L+10)
for i := range memo {
memo[i] = -1
}
var grundy func(int) int
grundy = func(len_ int) int {
if memo[len_] != -1 {
return memo[len_]
}
// 枚举分割长度
nextStates := make(map[int]struct{})
for len1 := 1; len1 < len_; len1++ {
for len2 := 1; len2 < len_; len2++ {
len3 := len_ - len1 - len2
if len1 < len2 && len2 < len3 && len3-len1 <= D {
nextStates[grundy(len1)^grundy(len2)^grundy(len3)] = struct{}{}
}
}
}
mex := 0
for {
if _, ok := nextStates[mex]; !ok {
break
}
mex++
}
memo[len_] = mex
return mex
}
// 先手はkadoくん、後手はmatsuくんです。
if grundy(L) == 0 {
fmt.Fprintln(out, "matsu") // lose
} else {
fmt.Fprintln(out, "kado") // win
}
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
func mins(nums ...int) int {
res := nums[0]
for _, num := range nums {
if num < res {
res = num
}
}
return res
}
func maxs(nums ...int) int {
res := nums[0]
for _, num := range nums {
if num > res {
res = num
}
}
return res
}