Skip to content

Commit 780ee39

Browse files
committed
+ problem 464
1 parent adb80ec commit 780ee39

File tree

5 files changed

+144
-0
lines changed

5 files changed

+144
-0
lines changed

Problemset/0464-Can I Win/README.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# 464. Can I Win
2+
In the "100 game" two players take turns adding, to a running total, any integer from `1` to `10`. The player who first causes the running total to **reach or exceed** 100 wins.
3+
4+
What if we change the game so that players **cannot** re-use integers?
5+
6+
For example, two players might take turns drawing from a common pool of numbers from 1 to 15 without replacement until they reach a total >= 100.
7+
8+
Given two integers `maxChoosableInteger` and `desiredTotal`, return `true` if the first player to move can force a win, otherwise, return `false`. Assume both players play **optimally**.
9+
10+
#### Example 1:
11+
<pre>
12+
<strong>Input:</strong> maxChoosableInteger = 10, desiredTotal = 11
13+
<strong>Output:</strong> false
14+
<strong>Explanation:</strong>
15+
No matter which integer the first player choose, the first player will lose.
16+
The first player can choose an integer from 1 up to 10.
17+
If the first player choose 1, the second player can only choose integers from 2 up to 10.
18+
The second player will win by choosing 10 and get a total = 11, which is >= desiredTotal.
19+
Same with other integers chosen by the first player, the second player will always win.
20+
</pre>
21+
22+
#### Example 2:
23+
<pre>
24+
<strong>Input:</strong> maxChoosableInteger = 10, desiredTotal = 0
25+
<strong>Output:</strong> true
26+
</pre>
27+
28+
#### Example 3:
29+
<pre>
30+
<strong>Input:</strong> maxChoosableInteger = 10, desiredTotal = 1
31+
<strong>Output:</strong> true
32+
</pre>
33+
34+
#### Constraints:
35+
* `1 <= maxChoosableInteger <= 20`
36+
* `0 <= desiredTotal <= 300`
37+
38+
## Solutions (Python)
39+
40+
### 1. Solution
41+
```Python
42+
from functools import cache
43+
44+
45+
class Solution:
46+
def canIWin(self, maxChoosableInteger: int, desiredTotal: int) -> bool:
47+
@cache
48+
def canIWinWithUsed(usedmask: int) -> bool:
49+
total = sum(i + 1 for i in range(maxChoosableInteger)
50+
if (usedmask >> i) & 1 == 1)
51+
52+
for i in range(maxChoosableInteger):
53+
if (usedmask >> i) & 1 == 0:
54+
if total + i + 1 >= desiredTotal or not canIWinWithUsed(usedmask | (1 << i)):
55+
return True
56+
57+
return False
58+
59+
return sum(range(1, maxChoosableInteger + 1)) >= desiredTotal and canIWinWithUsed(0)
60+
```
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# 464. 我能赢吗
2+
在 "100 game" 这个游戏中,两名玩家轮流选择从 `1``10` 的任意整数,累计整数和,先使得累计整数和 **达到或超过** 100 的玩家,即为胜者。
3+
4+
如果我们将游戏规则改为 “玩家 **不能** 重复使用整数” 呢?
5+
6+
例如,两个玩家可以轮流从公共整数池中抽取从 1 到 15 的整数(不放回),直到累计整数和 >= 100。
7+
8+
给定两个整数 `maxChoosableInteger` (整数池中可选择的最大数)和 `desiredTotal`(累计和),若先出手的玩家能稳赢则返回 `true` ,否则返回 `false` 。假设两位玩家游戏时都表现 **最佳**
9+
10+
#### 示例 1:
11+
<pre>
12+
<strong>输入:</strong> maxChoosableInteger = 10, desiredTotal = 11
13+
<strong>输出:</strong> false
14+
<strong>解释:</strong>
15+
无论第一个玩家选择哪个整数,他都会失败。
16+
第一个玩家可以选择从 1 到 10 的整数。
17+
如果第一个玩家选择 1,那么第二个玩家只能选择从 2 到 10 的整数。
18+
第二个玩家可以通过选择整数 10(那么累积和为 11 >= desiredTotal),从而取得胜利.
19+
同样地,第一个玩家选择任意其他整数,第二个玩家都会赢。
20+
</pre>
21+
22+
#### 示例 2:
23+
<pre>
24+
<strong>输入:</strong> maxChoosableInteger = 10, desiredTotal = 0
25+
<strong>输出:</strong> true
26+
</pre>
27+
28+
#### 示例 3:
29+
<pre>
30+
<strong>输入:</strong> maxChoosableInteger = 10, desiredTotal = 1
31+
<strong>输出:</strong> true
32+
</pre>
33+
34+
#### 提示:
35+
* `1 <= maxChoosableInteger <= 20`
36+
* `0 <= desiredTotal <= 300`
37+
38+
## 题解 (Python)
39+
40+
### 1. 题解
41+
```Python
42+
from functools import cache
43+
44+
45+
class Solution:
46+
def canIWin(self, maxChoosableInteger: int, desiredTotal: int) -> bool:
47+
@cache
48+
def canIWinWithUsed(usedmask: int) -> bool:
49+
total = sum(i + 1 for i in range(maxChoosableInteger)
50+
if (usedmask >> i) & 1 == 1)
51+
52+
for i in range(maxChoosableInteger):
53+
if (usedmask >> i) & 1 == 0:
54+
if total + i + 1 >= desiredTotal or not canIWinWithUsed(usedmask | (1 << i)):
55+
return True
56+
57+
return False
58+
59+
return sum(range(1, maxChoosableInteger + 1)) >= desiredTotal and canIWinWithUsed(0)
60+
```

Problemset/0464-Can I Win/Solution.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from functools import cache
2+
3+
4+
class Solution:
5+
def canIWin(self, maxChoosableInteger: int, desiredTotal: int) -> bool:
6+
@cache
7+
def canIWinWithUsed(usedmask: int) -> bool:
8+
total = sum(i + 1 for i in range(maxChoosableInteger)
9+
if (usedmask >> i) & 1 == 1)
10+
11+
for i in range(maxChoosableInteger):
12+
if (usedmask >> i) & 1 == 0:
13+
if total + i + 1 >= desiredTotal or not canIWinWithUsed(usedmask | (1 << i)):
14+
return True
15+
16+
return False
17+
18+
return sum(range(1, maxChoosableInteger + 1)) >= desiredTotal and canIWinWithUsed(0)

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@
334334
[461][461l] |[Hamming Distance][461] |![rs]
335335
[462][462l] |[Minimum Moves to Equal Array Elements II][462] |![rs]
336336
[463][463l] |[Island Perimeter][463] |![rs]
337+
[464][464l] |[Can I Win][464] |![py]
337338
[467][467l] |[Unique Substrings in Wraparound String][467] |![rb]&nbsp;&nbsp;![rs]
338339
[468][468l] |[Validate IP Address][468] |![rs]
339340
[470][470l] |[Implement Rand10() Using Rand7()][470] |![rs]
@@ -2045,6 +2046,7 @@
20452046
[461]:Problemset/0461-Hamming%20Distance/README.md#461-hamming-distance
20462047
[462]:Problemset/0462-Minimum%20Moves%20to%20Equal%20Array%20Elements%20II/README.md#462-minimum-moves-to-equal-array-elements-ii
20472048
[463]:Problemset/0463-Island%20Perimeter/README.md#463-island-perimeter
2049+
[464]:Problemset/0464-Can%20I%20Win/README.md#464-can-i-win
20482050
[467]:Problemset/0467-Unique%20Substrings%20in%20Wraparound%20String/README.md#467-unique-substrings-in-wraparound-string
20492051
[468]:Problemset/0468-Validate%20IP%20Address/README.md#468-validate-ip-address
20502052
[470]:Problemset/0470-Implement%20Rand10\(\)%20Using%20Rand7\(\)/README.md#470-implement-rand10-using-rand7
@@ -3750,6 +3752,7 @@
37503752
[461l]:https://leetcode.com/problems/hamming-distance/
37513753
[462l]:https://leetcode.com/problems/minimum-moves-to-equal-array-elements-ii/
37523754
[463l]:https://leetcode.com/problems/island-perimeter/
3755+
[464l]:https://leetcode.com/problems/can-i-win/
37533756
[467l]:https://leetcode.com/problems/unique-substrings-in-wraparound-string/
37543757
[468l]:https://leetcode.com/problems/validate-ip-address/
37553758
[470l]:https://leetcode.com/problems/implement-rand10-using-rand7/

README_CN.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@
334334
[461][461l] |[汉明距离][461] |![rs]
335335
[462][462l] |[最少移动次数使数组元素相等 II][462] |![rs]
336336
[463][463l] |[岛屿的周长][463] |![rs]
337+
[464][464l] |[我能赢吗][464] |![py]
337338
[467][467l] |[环绕字符串中唯一的子字符串][467] |![rb]&nbsp;&nbsp;![rs]
338339
[468][468l] |[验证IP地址][468] |![rs]
339340
[470][470l] |[用 Rand7() 实现 Rand10()][470] |![rs]
@@ -2045,6 +2046,7 @@
20452046
[461]:Problemset/0461-Hamming%20Distance/README_CN.md#461-汉明距离
20462047
[462]:Problemset/0462-Minimum%20Moves%20to%20Equal%20Array%20Elements%20II/README_CN.md#462-最少移动次数使数组元素相等-ii
20472048
[463]:Problemset/0463-Island%20Perimeter/README_CN.md#463-岛屿的周长
2049+
[464]:Problemset/0464-Can%20I%20Win/README_CN.md#464-我能赢吗
20482050
[467]:Problemset/0467-Unique%20Substrings%20in%20Wraparound%20String/README_CN.md#467-环绕字符串中唯一的子字符串
20492051
[468]:Problemset/0468-Validate%20IP%20Address/README_CN.md#468-验证ip地址
20502052
[470]:Problemset/0470-Implement%20Rand10\(\)%20Using%20Rand7\(\)/README_CN.md#470-用-Rand7-实现-Rand10
@@ -3750,6 +3752,7 @@
37503752
[461l]:https://leetcode.cn/problems/hamming-distance/
37513753
[462l]:https://leetcode.cn/problems/minimum-moves-to-equal-array-elements-ii/
37523754
[463l]:https://leetcode.cn/problems/island-perimeter/
3755+
[464l]:https://leetcode.cn/problems/can-i-win/
37533756
[467l]:https://leetcode.cn/problems/unique-substrings-in-wraparound-string/
37543757
[468l]:https://leetcode.cn/problems/validate-ip-address/
37553758
[470l]:https://leetcode.cn/problems/implement-rand10-using-rand7/

0 commit comments

Comments
 (0)