LeetCode 第 165 场周赛

LeetCode 第 165 场周赛

5275. 找出井字棋的获胜者

5276. 不浪费原料的汉堡制作方案

5277. 统计全为 1 的正方形子矩阵

5278. 分割回文串 III

C 暴力做的,只能说数据不充分

找出井字棋的获胜者4

题目描述 Description

A 和 B 在一个 3 x 3 的网格上玩井字棋。

井字棋游戏的规则如下:

玩家轮流将棋子放在空方格 (" ") 上。
第一个玩家 A 总是用 "X" 作为棋子,而第二个玩家 B 总是用 "O" 作为棋子。
"X" 和 "O" 只能放在空方格中,而不能放在已经被占用的方格上。
只要有 3 个相同的(非空)棋子排成一条直线(行、列、对角线)时,游戏结束。
如果所有方块都放满棋子(不为空),游戏也会结束。
游戏结束后,棋子无法再进行任何移动。

给你一个数组 moves,其中每个元素是大小为 2 的另一个数组(元素分别对应网格的行和列),它按照 A 和 B 的行动顺序(先 A 后 B)记录了两人各自的棋子位置。

如果游戏存在获胜者(A 或 B),就返回该游戏的获胜者;如果游戏以平局结束,则返回 "Draw";如果仍会有行动(游戏未结束),则返回 "Pending"。

你可以假设 moves 都 有效(遵循井字棋规则),网格最初是空的,A 将先行动。

样例输入与样例输出 Sample Input and Sample Output

示例 1:

  输入:moves = [[0,0],[2,0],[1,1],[2,1],[2,2]]
  输出:"A"
  解释:"A" 获胜,他总是先走。
  "X  "    "X  "    "X  "    "X  "    "X  "
  "   " -> "   " -> " X " -> " X " -> " X "
  "   "    "O  "    "O  "    "OO "    "OOX"

示例 2:

  输入:moves = [[0,0],[1,1],[0,1],[0,2],[1,0],[2,0]]
  输出:"B"
  解释:"B" 获胜。
  "X  "    "X  "    "XX "    "XXO"    "XXO"    "XXO"
  "   " -> " O " -> " O " -> " O " -> "XO " -> "XO "
  "   "    "   "    "   "    "   "    "   "    "O  "

示例 3:

输入:moves = [[0,0],[1,1],[2,0],[1,0],[1,2],[2,1],[0,1],[0,2],[2,2]]
输出:"Draw"
输出:由于没有办法再行动,游戏以平局结束。
"XXO"
"OOX"
"XOX"

示例 4:

输入:moves = [[0,0],[1,1]]
输出:"Pending"
解释:游戏还没有结束。
"X "
" O "
" "

提示 Hint

提示:

1 <= moves.length <= 9
moves[i].length == 2
0 <= moves[i][j] <= 2
moves 里没有重复的元素。
moves 遵循井字棋的规则。

题解

模拟即可,考虑到 3x3 有看到位运算的做法

代码

class Solution {
 public:

  int run(int g[3][3], vector<int>&move, int val) {
    g[move[0]][move[1]] = val;
    int t = 0, ans = 0;
    for(int i = move[0]; i < 3; ++i) {
      if(g[i][move[1]] == val)
        t++;
      else
        break;
    }
    for(int i = move[0] - 1; i >= 0; --i) {
      if(g[i][move[1]] == val)
        t++;
      else
        break;
    }
    ans = max(ans, t);
    t = 0;

    for(int i = move[1]; i < 3; ++i) {
      if(g[move[0]][i] == val)
        t++;
      else
        break;
    }
    for(int i = move[1] - 1; i >= 0; --i) {
      if(g[move[0]][i] == val)
        t++;
      else
        break;
    }
    ans = max(ans, t);
    t = 0;

    for(int i = 0; i + move[0] < 3 && i + move[1] < 3; ++i) {
      if(g[i + move[0]][i + move[1]] == val)
        t++;
      else
        break;
    }
    for(int i = -1; i + move[0] >= 0 && i + move[1] >= 0; --i) {
      if(g[i + move[0]][i + move[1]] == val)
        t++;
      else
        break;
    }
    ans = max(ans, t);
    t = 0;

    for(int i = 0; i + move[0] < 3 && move[1] - i >= 0; ++i) {
      if(g[i + move[0]][-i + move[1]] == val)
        t++;
      else
        break;
    }
    for(int i = -1; i + move[0] >= 0 && move[1] - i < 3 ; --i) {
      if(g[i + move[0]][-i + move[1]] == val)
        t++;
      else
        break;
    }
    ans = max(ans, t);
    t = 0;

    return ans;
  }
  bool finished(int g[3][3]) {
    for(int i = 0; i < 3; ++i)
      for(int j = 0; j < 3; ++j)
        if(g[i][j] == 0)
          return false;
    return true;
  }
  string tictactoe(vector<vector<int>>& moves) {
    int g[3][3];
    memset(g, 0, sizeof(g));
    for(int i = 0, n = moves.size(); i < n; ++i) {
      if(run(g, moves[i], i % 2 + 1) > 2)
        return (i & 1) ?  string("B") : string("A");
    }
    return finished(g) ? string("Draw") : string("Pending");
  }
};

不浪费原料的汉堡制作方案4

5276. 不浪费原料的汉堡制作方案

题目描述 Description

圣诞活动预热开始啦,汉堡店推出了全新的汉堡套餐。为了避免浪费原料,请你帮他们制定合适的制作计划。

给你两个整数 tomatoSlices 和 cheeseSlices,分别表示番茄片和奶酪片的数目。不同汉堡的原料搭配如下:

巨无霸汉堡:4 片番茄和 1 片奶酪
小皇堡:2 片番茄和 1 片奶酪

请你以 [total_jumbo, total_small]([巨无霸汉堡总数,小皇堡总数])的格式返回恰当的制作方案,使得剩下的番茄片 tomatoSlices 和奶酪片 cheeseSlices 的数量都是 0。

如果无法使剩下的番茄片 tomatoSlices 和奶酪片 cheeseSlices 的数量为 0,就请返回 []。

样例输入与样例输出 Sample Input and Sample Output

示例 1:

输入:tomatoSlices = 16, cheeseSlices = 7
输出:[1,6]
解释:制作 1 个巨无霸汉堡和 6 个小皇堡需要 41 + 26 = 16 片番茄和 1 + 6 = 7 片奶酪。不会剩下原料。

示例 2:

输入:tomatoSlices = 17, cheeseSlices = 4
输出:[]
解释:只制作小皇堡和巨无霸汉堡无法用光全部原料。

示例 3:

输入:tomatoSlices = 4, cheeseSlices = 17
输出:[]
解释:制作 1 个巨无霸汉堡会剩下 16 片奶酪,制作 2 个小皇堡会剩下 15 片奶酪。

示例 4:

输入:tomatoSlices = 0, cheeseSlices = 0
输出:[0,0]

示例 5:

输入:tomatoSlices = 2, cheeseSlices = 1
输出:[0,1]

提示 Hint

提示:

0 <= tomatoSlices <= 10^7
0 <= cheeseSlices <= 10^7

题解

先考虑全部用作小皇堡,剩下的每 2 片番茄将一个小皇堡换成巨无霸汉堡。注意边界和特判。

代码

class Solution {
 public:
  vector<int> numOfBurgers(int tomatoSlices, int cheeseSlices) {
    if(tomatoSlices > cheeseSlices * 4)
      return vector<int> {};
    vector<int> ans(2);
    ans[1] = cheeseSlices;
    tomatoSlices -= 2 * cheeseSlices;
    if(tomatoSlices < 0 || (tomatoSlices & 1))
      return vector<int> {};
    ans[1] -= tomatoSlices / 2;
    ans[0] += tomatoSlices / 2;
    tomatoSlices -= tomatoSlices - (tomatoSlices & 1);
    if(tomatoSlices != 0)
      return vector<int> {};
    return ans;
  }
};

统计全为 1 的正方形子矩阵5

5277. 统计全为 1 的正方形子矩阵

题目描述 Description

给你一个 m * n 的矩阵,矩阵中的元素不是 0 就是 1,请你统计并返回其中完全由 1 组成的 正方形 子矩阵的个数。

样例输入与样例输出 Sample Input and Sample Output

示例 1:

输入:matrix =
[
[0,1,1,1],
[1,1,1,1],
[0,1,1,1]
]
输出:15
解释:
边长为 1 的正方形有 10 个。
边长为 2 的正方形有 4 个。
边长为 3 的正方形有 1 个。
正方形的总数 = 10 + 4 + 1 = 15.

示例 2:

输入:matrix =
[
[1,0,1],
[1,1,0],
[1,1,0]
]
输出:7
解释:
边长为 1 的正方形有 6 个。
边长为 2 的正方形有 1 个。
正方形的总数 = 6 + 1 = 7.

提示 Hint

1 <= arr.length <= 300
1 <= arr[0].length <= 300
0 <= arr[i][j] <= 1

题解

暴力可过,显然数据强度不够。

代码

class Solution {
 public:
  int n, m;
  int countSquares(vector<vector<int>>& matrix) {
    n = matrix.size(), m = matrix[0].size();
    int ans(0);
    for(int i = 1, c; i <= min(n, m); ++i) {
      c = count(matrix, i);
      ans += c;
      if(!c)
        break;
    }
    return ans;
  }
  int count(vector<vector<int> >&matrix, int edgeLen) {
    int ans(0);
    for(int i = 0; i < n - edgeLen + 1; ++i) {
      for(int j = 0; j < m - edgeLen + 1; ++j)
        if(isSquareAllOne(matrix, i, j, edgeLen))
          ans++;
    }
    return ans;
  }

  bool isSquareAllOne(vector<vector<int>>&matrix, int x, int y, int edgeLen) {
    for(int i = 0; i < edgeLen; ++i) {
      for(int j = 0; j < edgeLen; ++j)
        if(!matrix[x + i][y + j])
          return false;
    }
    return true;
  }
};

分割回文串 III

5278. 分割回文串 III

题目描述 Description

给你一个由小写字母组成的字符串 s,和一个整数 k。

请你按下面的要求分割字符串:

首先,你可以将 s 中的部分字符修改为其他的小写英文字母。
接着,你需要把 s 分割成 k 个非空且不相交的子串,并且每个子串都是回文串。

请返回以这种方式分割字符串所需修改的最少字符数。

样例输入与样例输出 Sample Input and Sample Output

示例 1:

输入:s = "abc", k = 2
输出:1
解释:你可以把字符串分割成 "ab" 和 "c",并修改 "ab" 中的 1 个字符,将它变成回文串。

示例 2:

输入:s = "aabbc", k = 3
输出:0
解释:你可以把字符串分割成 "aa"、"bb" 和 "c",它们都是回文串。

示例 3:

输入:s = "leetcode", k = 8
输出:0

提示 Hint

1 <= k <= s.length <= 100
s 中只含有小写英文字母。

题解

dp[i][j] 表示以 i 结尾,分成 j 段的最少修改次数。枚举上一段结尾的位置 pre,dp[i][j] = min(dp[i][j],dp[pre][j-1])

代码

class Solution {
 public:
  int palindromePartition(string s, int k) {
    int dp[s.length()][k + 1];
    memset(dp, 0x3f, sizeof(dp));
    for(int i = 0; i < s.length(); ++i) { // end with s[i]
      for(int j = 1; j <= k && j <= i + 1; ++j) { // has j segments
        if(j == 1)
          dp[i][j] = transferCost(s, 0, i);
        else
          for(int pre = max(j - 2, 0); pre < i; ++pre) {
            dp[i][j] = min(dp[i][j], dp[pre][j - 1] + transferCost(s, pre + 1, i));
          }
      }
    }
    return dp[s.length() - 1][k];
  }
  int transferCost(string s, int l, int r) {
    int ans(0);
    for(int i = 0; i < (r - l + 1) / 2; ++i)
      if(s[i + l] != s[r - i])
        ans++;
    return ans;
  }
};

原文地址:https://www.cnblogs.com/Forgenvueory/p/11967336.html

时间: 2024-10-26 03:19:20

LeetCode 第 165 场周赛的相关文章

Leetcode 第174场周赛 题解

Leetcode 第174场周赛 题解 方阵中战斗力最弱的 K 行 签到题,统计一下每行的军人数量,然后设置一下排序规则即可. 时间复杂度 \(O(nlogn)\) typedef long long ll; typedef double db; #define _for(i,a,b) for(int i = (a);i < b;i ++) #define _rep(i,a,b) for(int i = (a);i > b;i --) #define INF 0x3f3f3f3f3f3f3f3

Leetcode 第175场周赛 题解(完结)

Leetcode 第175场周赛 题解 检查整数及其两倍数是否存在 数据范围小的可怜,\(O(n^2)\) 解法可行.如果范围大一点,可以先进行排序然后遍历每一个数进行二分查找,时间复杂度 \(O(nlogn)\) 代码是平方解法. typedef long long ll; typedef double db; #define _for(i,a,b) for(int i = (a);i < b;i ++) #define _rep(i,a,b) for(int i = (a);i > b;i

LeetCode 第 183 场周赛

LeetCode 第 183 场周赛 非递增顺序的最小子序列 降序排列后,往 vector<int>ans 中添加元素,直到其和超过所有元素和的一半. class Solution { public: vector<int> minSubsequence(vector<int>& nums) { const int n = nums.size(); sort(nums.begin(), nums.end(), greater<int>()); int

LeetCode第136场周赛

菜鸡我只做出了一道... 5055. 困于环中的机器人 在无限的平面上,机器人最初位于 (0, 0) 处,面朝北方.机器人可以接受下列三条指令之一: "G":直走 1 个单位 "L":左转 90 度 "R":右转 90 度 机器人按顺序执行指令 instructions,并一直重复它们. 只有在平面中存在环使得机器人永远无法离开时,返回 true.否则,返回 false. 提示: 1 <= instructions.length <=

LeetCode 第133场周赛总结

1029. 两地调度 公司计划面试 2N 人.第 i 人飞往 A 市的费用为 costs[i][0],飞往 B 市的费用为 costs[i][1]. 返回将每个人都飞到某座城市的最低费用,要求每个城市都有 N 人抵达. 示例: 输入:[[10,20],[30,200],[400,50],[30,20]] 输出:110 解释: 第一个人去 A 市,费用为 10. 第二个人去 A 市,费用为 30. 第三个人去 B 市,费用为 50. 第四个人去 B 市,费用为 20. 最低总费用为 10 + 30

LeetCode 第 149 场周赛

一.一年中的第几天(LeetCode-1154) 1.1 题目描述 1.2 解题思路 比较水的一题,搞清楚平年.闰年的判定规则,就很容易做出来. 1.3 解题代码 class Solution { public int ordinalOfDate(String date) { String[] dateArray = date.split("-"); int year = Integer.parseInt(dateArray[0]); int month = Integer.parse

LeetCode 第 155 场周赛

成绩 第二题尝试了两种解法,一种超时间.一种超内存,只AC了一题.归根结底还是太菜. 一.最小绝对差(LeetCode-5189) 1.1 题目描述 1.2 解题思路 数组排好序,获取最小的差值即可. 1.3 解题代码 public class Solution { class Test { public List<Integer> list; public Integer num; } public List<List<Integer>> minimumAbsDiff

leetcode第 181 场周赛

5364. 按既定顺序创建目标数组 给你两个整数数组 nums 和 index.你需要按照以下规则创建目标数组: 目标数组 target 最初为空. 按从左到右的顺序依次读取 nums[i] 和 index[i],在 target 数组中的下标 index[i] 处插入值 nums[i] . 重复上一步,直到在 nums 和 index 中都没有要读取的元素. 请你返回目标数组. 题目保证数字插入位置总是存在. 示例 1: 输入:nums = [0,1,2,3,4], index = [0,1,

leetcode 第184场周赛第一题(数组中的字符串匹配)

一.函数的运用 1,strstr(a,b); 判断b是否为a的子串,如果是,返回从b的开头开始到a的结尾 如“abcdefgh” “de” 返回“defgh”: 如果不是子串,返回NULL: 2,memcpy(a,b+n,c); 将b串从第n位后的c个字符串复制到a中,返回a串: (注:做完函数后需要添加上b[c] = '\0') 如果吧b+n换成b就是从头开始 将代码换成 memcpy(arr[cnt], words[i], strlen(words[i])+1); 就是直接复制words[i