3274. 检查棋盘方格颜色是否相同
- 给你两个字符串 coordinate1 和 coordinate2,代表 8 x 8 国际象棋棋盘上的两个方格的坐标。
以下是棋盘的参考图。
如果这两个方格颜色相同,返回 true,否则返回 false。
分析问题:
由图知,假设a、b… … 用 1、2… … 代表,则黑色方格的行标和列表的奇偶性一定相同,反之为白格。
class Solution {
public:
bool check(string a) {
int x = a[0] - 'a' + 1, y = a[1] - '0';
return (x&1) ^ (y&1);
}
bool checkTwoChessboards(string c1, string c2) {
return !(check(c1) ^ check(c2));
}
};
3275. 第 K 近障碍物查询
有一个无限大的二维平面。
给你一个正整数 k ,同时给你一个二维数组 queries ,包含一系列查询:
queries[i] = [x, y] :在平面上坐标 (x, y) 处建一个障碍物,数据保证之前的查询 不会 在这个坐标处建立任何障碍物。
每次查询后,你需要找到离原点第 k 近 障碍物到原点的 距离 。
请你返回一个整数数组 results ,其中 results[i] 表示建立第 i 个障碍物以后,离原地第 k 近障碍物距离原点的距离。如果少于 k 个障碍物,results[i] == -1 。
注意,一开始 没有 任何障碍物。
坐标在 (x, y) 处的点距离原点的距离定义为 |x| + |y| 。
示例 1:
输入:queries = [[1,2],[3,4],[2,3],[-3,0]], k = 2
输出:[-1,7,5,3]
解释:
最初,不存在障碍物。
queries[0] 之后,少于 2 个障碍物。
queries[1] 之后, 两个障碍物距离原点的距离分别为 3 和 7 。
queries[2] 之后,障碍物距离原点的距离分别为 3 ,5 和 7 。
queries[3] 之后,障碍物距离原点的距离分别为 3,3,5 和 7 。
示例 2:
输入:queries = [[5,5],[4,4],[3,3]], k = 1
输出:[10,8,6]
解释:
queries[0] 之后,只有一个障碍物,距离原点距离为 10 。
queries[1] 之后,障碍物距离原点距离分别为 8 和 10 。
queries[2] 之后,障碍物距离原点的距离分别为 6, 8 和10 。
提示:
1 <= queries.length <= 2 * 105
所有 queries[i] 互不相同。
-109 <= queries[i][0], queries[i][1] <= 109
1 <= k <= 105
分析:
使用优先队列,当队列大小达到k时,弹出堆顶元素。
需要注意的点是:维护队列的操作顺序是,先加入元素,再弹出多余元素,最后取top值。
struct my_cmp {
bool operator()(const pair<int, int>& a, const pair<int, int>& b) const {
return abs(a.first) + abs(a.second) - abs(b.first) - abs(b.second) < 0;
}
};
class Solution {
public:
vector<int> resultsArray(vector<vector<int>>& qs, int k) {
priority_queue<pair<int, int>, vector<pair<int, int>>, my_cmp> q;
int n = qs.size();
vector<int> ans;
for (int i = 0; i < n; i++) {
int t = abs(qs[i][0]) + abs(qs[i][1]);
q.push({qs[i][0], qs[i][1]});
if (i > k-1) q.pop();
if (i >= k-1) {
pair<int, int> tp = q.top();
ans.push_back(abs(tp.first) + abs(tp.second));
}else {
ans.push_back(-1);
}
}
return ans;
}
};
选择矩阵中单元格的最大得分
给你一个由正整数构成的二维矩阵 grid。
你需要从矩阵中选择 一个或多个 单元格,选中的单元格应满足以下条件:
- 所选单元格中的任意两个单元格都不会处于矩阵的 同一行。
- 所选单元格的值 互不相同。
你的得分为所选单元格值的总和。
返回你能获得的 最大 得分。
示例 1:
输入: grid = [[1,2,3],[4,3,2],[1,1,1]]
输出: 8
解释:
选择上图中用彩色标记的单元格,对应的值分别为 1、3 和 4 。
示例 2:
输入: grid = [[8,7,6],[8,3,2]]
输出: 15
解释:
选择上图中用彩色标记的单元格,对应的值分别为 7 和 8 。
提示:
1 <= grid.length, grid[i].length <= 10
1 <= grid[i][j] <= 100
我想出的答案:将矩阵中所有方格每一行存放,按值从大到小排列,枚举每一种符合答案的方案求最大。复杂度为 n n n^n nn,最大复杂度为 1 0 1 0 10^10 1010。本题需要注意的点是g的行数和列数不一定相等。
const int N = 15;
class Solution {
public:
int ans = 0, n, sum = 0;
int ar[N];
int g[N][N];
void dfs(int x, int y) {
if (x==n) {
if (ans < sum) {
ans = sum;
for(int i=0; i < x; i++) cout << ar[i] << " ";
cout << endl;
}
return;
}
for (int i = y; i < n; i++) {
bool fl = false;
ar[x] = g[x][i];
for (int j = 0; j < x; j++) {
if (ar[j] == ar[x]) {
fl = true;
break;
}
}
if (!fl) {
sum += g[x][i];
dfs(x+1, 0);
sum -= g[x][i];
}
}
}
int maxScore(vector<vector<int>>& gt) {
n = gt.size();
for (int i =0; i < n; i++) {
for (int j =0; j < n; j++)
g[i][j] = gt[i][j];
}
dfs(0, 0);
return ans;
}
};
标答:枚举每一个数,再枚举所有符合条件的答案。要使用二维数组存储中间结果,否则会超时。
x&-x的结果取决于x的二进制表示中最低位的值。
class Solution {
public:
int n = 0, m = 0;
map<int, int> mp;
vector<int> nums;
int memo[105][1 << 10];
int dfs(vector<vector<int>>& g, int pos, int rs) {
if (pos < 0) return 0;
int res = memo[pos][rs];
if (res != -1) return res;
res = dfs(g, pos-1, rs);
// 枚举每行
for (int t = mp[nums[pos]], lb; t; t ^= lb) {
lb = t & -t;
if (rs & lb) continue;
res = max(res, dfs(g, pos-1, rs | lb) + nums[pos]);
}
memo[pos][rs] = res;
return res;
}
int maxScore(vector<vector<int>>& g) {
n = g.size(), m = g[0].size();
for (int i = 0; i < 105; i++)
memset(memo[i], -1, sizeof memo[i]);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
int x = g[i][j];
mp[x] |= 1 << i;
}
}
for (auto& [x,_] : mp) {
nums.push_back(x);
}
return dfs(g, nums.size()-1, 0);
}
};
3277. 查询子数组最大异或值
给你一个由 n 个整数组成的数组 nums,以及一个大小为 q 的二维整数数组 queries,其中 queries[i] = [li, ri]。
对于每一个查询,你需要找出 nums[li..ri] 中任意
子数组
的 最大异或值。
数组的异或值 需要对数组 a 反复执行以下操作,直到只剩一个元素,剩下的那个元素就是 异或值:
对于除最后一个下标以外的所有下标 i,同时将 a[i] 替换为 a[i] XOR a[i + 1] 。
移除数组的最后一个元素。
返回一个大小为 q 的数组 answer,其中 answer[i] 表示查询 i 的答案。
示例 1:
输入: nums = [2,8,4,32,16,1], queries = [[0,2],[1,4],[0,5]]
输出: [12,60,60]
解释:
在第一个查询中,nums[0..2] 的子数组分别是 [2], [8], [4], [2, 8], [8, 4], 和 [2, 8, 4],它们的异或值分别为 2, 8, 4, 10, 12, 和 6。查询的答案是 12,所有异或值中的最大值。
在第二个查询中,nums[1..4] 的子数组中最大的异或值是子数组 nums[1..4] 的异或值,为 60。
在第三个查询中,nums[0..5] 的子数组中最大的异或值是子数组 nums[1..4] 的异或值,为 60。
示例 2:
输入: nums = [0,7,3,2,8,5,1], queries = [[0,3],[1,5],[2,4],[2,6],[5,6]]
输出: [7,14,11,14,5]
解释:
下标 nums[li..ri] 最大异或值子数组 子数组最大异或值
0 [0, 7, 3, 2] [7] 7
1 [7, 3, 2, 8, 5] [7, 3, 2, 8] 14
2 [3, 2, 8] [3, 2, 8] 11
3 [3, 2, 8, 5, 1] [2, 8, 5, 1] 14
4 [5, 1] [5] 5
提示:
1 <= n == nums.length <= 2000
0 <= nums[i] <= 231 - 1
1 <= q == queries.length <= 105
queries[i].length == 2
queries[i] = [li, ri]
0 <= li <= ri <= n - 1
class Solution {
public:
vector<int> maximumSubarrayXor(vector<int>& ns, vector<vector<int>>& q) {
int n = ns.size(), m = q.size();
vector<int> ans;
for (int i = 0; i < m; i++) {
int l = q[i][0], r = q[i][1], res = ns[r];
for (int x = l; x < r; x++) {
res = max(res, ns[x]);
for (int y = x + 1; y <= r; y++) {
res = max(res, ns[x] ^ ns[y]);
}
}
ans.push_back(res);
}
return ans;
}
};