下棋游戏
题目描述
小红和朋友玩游戏,棋盘为nxm的坐标轴。有一颗棋子在坐标(1,1)的位置,每次可以向上或者向右移动奇数个单位,不能移动到棋盘外面,无法行动就输了,小红先手,请问小红能否必胜。
输入描述
一行一个整数t,表示有t组数据。
接下来t行,每行两个整数n和m,表示棋盘大小。
1 <= t <= 10^4
1 <= n, m < 10^3
输出描述
对于每组数据,输出一行,如果小红必胜,输出Yes,否则输出No
示例
输入
4
1 1
1 4
4 1
4 4
输出
No
Yes
Yes
No
说明
样例一,棋盘大小为1x1,小红无法行动,输了。
样例二,棋盘大小为1x4,小红第一次向右移动3个单位,小红获胜,朋友无法行动。
样例三,棋盘大小为4x1,小红第一次向上移动3个单位,小红获胜,朋友无法行动。
解题思路
非常简单的找规律模拟题!听过课上讲过的LeetCode 292、Nim 游戏,LeetCode 1025、除数博弈等博弈类型题目的同学,遇到这题肯定直接秒了。
基本思路为:当m+n为奇数时输出Yes,否则为No;
- 当m+n为奇数时,可以选择直接跳到偶数那一边的最后一个格子,然后剩奇数格的那条边,这个时候无论后手走几步都无法到达死角;
- 当m+n为偶数时,无论走几格,都会陷入对方先手的第一种情况,必输。
代码
作者:闭着眼睛学数理化
参加算法训练营添加微信:278166530
def get_ans(n, m):
return "Yes" if (n+m) % 2 == 1 else "No"
t = int(input())
ans = list()
for _ in range(t):
n, m = map(int, input().split())
ans.append(get_ans(n, m))
for s in ans:
print(s)
时空复杂度
时间复杂度:O(t)。单次判断的时间复杂度为O(1),一共有t组数据。
空间复杂度:O(1)。仅需若干常数变量。
讨厌鬼的组合帖子
题目描述
讨厌鬼有n个帖子。第i个帖子的点赞数为ai,点踩数为bi。你可以选择任意个帖子组合起来。
组合帖子的点赞数和点踩数为所有被组合帖子点赞数和点踩数之和。已知一个帖子的点赞数为x,点踩数为y,则该帖子的吸引度为|x-y|。讨厌鬼需要选择若干个帖子组合起来,使得这个组合帖子的吸引度尽可能大。请你告诉他这个吸引度最大是多少?
输入描述
第一行输入一个整数n (1 <= n <= 10^5)
第二行输入n个整数ai (1 <= ai <= 10^9)
第三行输入n个整数bi (1 <= bi <= 10^9)
输出描述
一行一个整数,表示最大吸引度。
示例
输入
4
4 2 1 1
2 1 4 4
输出
6
说明
选择第 3 个和第 4 个帖子组合后,点赞数为 2,点踩数为 8,吸引度为|2-8|= 6
解题思路
题目要求计算的是点赞数的和 减去点踩数的和 的绝对值的最大值,我们可以先构建数组diff_list来表示第i个帖子的点赞数与点踩数之差,即
diff_list = [ai - bi for ai, bi in zip(a_list, b_list)]
显然diff_list包含若干正数(点赞数多的情况)和若干负数(点踩数多的情况)。
为了使得总的吸引度尽可能地大,我们贪心地分别令diff_list中的所有正数相加和所有负数相加,得到的两个和中绝对值的较大值即为答案。
PS:本题也可以看作是一个背包问题,每个元素存在选或不选两种状态,但这样思考问题就会变得有些复杂了。
代码
作者:闭着眼睛学数理化
参加算法训练营添加微信:278166530
n = int(input())
a_list = list(map(int, input().split()))
b_list = list(map(int, input().split()))
构建diff_list列表
diff_list = [ai - bi for ai, bi in zip(a_list, b_list)]
初始化正数和sum1和负数和sum2
sum1 = 0
sum2 = 0
遍历diff_list中的所有元素num
for num in diff_list:
num为正,加入sum1中,否则加入num2中
if num > 0:
sum1 += num
else:
sum2 += num
取两者之间绝对值的较大值即为答案
print(max(sum1, -sum2))
时空复杂度
时间复杂度:O(N)。构建diff_list,计算最大值和最小值求和均需要O(N)的时间复杂度。
空间复杂度:O(N)。diff_list所占空间。