結果

問題 No.361 門松ゲーム2
ユーザー 草苺奶昔草苺奶昔
提出日時 2023-02-21 17:13:50
言語 Go
(1.22.1)
結果
AC  
実行時間 167 ms / 2,000 ms
コード長 1,563 bytes
コンパイル時間 12,425 ms
コンパイル使用メモリ 201,240 KB
実行使用メモリ 4,384 KB
最終ジャッジ日時 2023-09-29 08:59:23
合計ジャッジ時間 14,231 ms
ジャッジサーバーID
(参考情報)
judge14 / judge15
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,380 KB
testcase_01 AC 2 ms
4,376 KB
testcase_02 AC 1 ms
4,380 KB
testcase_03 AC 1 ms
4,376 KB
testcase_04 AC 2 ms
4,376 KB
testcase_05 AC 2 ms
4,376 KB
testcase_06 AC 1 ms
4,376 KB
testcase_07 AC 2 ms
4,376 KB
testcase_08 AC 1 ms
4,384 KB
testcase_09 AC 2 ms
4,380 KB
testcase_10 AC 2 ms
4,376 KB
testcase_11 AC 1 ms
4,376 KB
testcase_12 AC 2 ms
4,376 KB
testcase_13 AC 1 ms
4,380 KB
testcase_14 AC 60 ms
4,380 KB
testcase_15 AC 2 ms
4,376 KB
testcase_16 AC 20 ms
4,376 KB
testcase_17 AC 8 ms
4,376 KB
testcase_18 AC 6 ms
4,376 KB
testcase_19 AC 5 ms
4,376 KB
testcase_20 AC 3 ms
4,380 KB
testcase_21 AC 22 ms
4,380 KB
testcase_22 AC 167 ms
4,376 KB
testcase_23 AC 2 ms
4,380 KB
testcase_24 AC 2 ms
4,376 KB
testcase_25 AC 3 ms
4,376 KB
testcase_26 AC 8 ms
4,380 KB
testcase_27 AC 11 ms
4,376 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

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
}
0