A.左右元素和的差值
做法:
模拟,前后缀和就行了,这里为了好写,我把给的数据复制一遍,放进了数组。
int l[1005], r[1005];
vector<int> leftRigthDifference(vector<int>& nums) {
int len = nums.size();
for (int i = 1; i <= len; i++) {
l[i] = l[i - 1] + nums[i - 1];
}
for (int i = len; i >= 1; i--) {
r[i] = r[i + 1] + nums[i - 1];
}
vector<int> ans;
for (int i = 1; i <= len; i++) {
ans.push_back(abs(l[i - 1] - r[i + 1]));
}
return ans;
}
B.找出字符串的可整除数组
题意:
给定字符串,问前缀代表的十进制数字,能不能被 m 整除。
做法:
模拟,但是我白白wa了两发,因为平时习惯 define int long long.
就寄寄了,因为爆 int。。。
vector<int> divisibilityArray(string word, int m) {
vector<int> ans;
int len = word.size();
long long x = 0;
for (int i = 0; i < len; i++) {
x = x * 10 + word[i] - '0';
ans.push_back(x % m == 0);
x %= m;
}
return ans;
}
C.求出最多标记下标
题意:
尽量的选择点对 (i,j),满足 ai∗2<=aj
做法:
先排序,分成两半,在大的那边中,找找小的这边能不能对上即可。
int maxNumOfMarkedIndices(vector<int>& nums) {
sort(nums.begin(), nums.end());
int CAONIMA = nums.size() / 2 - 1, ans = 0;
for (int i = nums.size() - 1; i >= nums.size() / 2; i--)
{
while (CAONIMA >= 0 && 2 * nums[CAONIMA] > nums[i])
CAONIMA--;
if (CAONIMA == -1)
break;
CAONIMA--;
ans += 2;
}
return ans;
}
D.在网格图中访问一个格子的最少时间
题意:
给定了二维矩阵,其中的点代表到达此处的最早时间,意思是你不能来的太早。
而且不可以停着不动,问最早什么时候到达右下角。
思路:
一眼 bfs。考虑到一个点可以被重复经过,于是改进了 bfs 的标记数组,只要能够松弛,那么这个点就可以再次被访问。
然后。。。
喜提 TLE
接着,笨蛋的我突然想到我这样做无异于经典的SPFA,那么岂不是可以用优先队列,也就是用 nlogn 的 dj。
于是重构代码,好在 dj 的代码难度很低,对于这题的矩阵,十几分钟之内也就写完了。
这题不用建边,对于一个点,往四个方向都访问一下就好了,建边反而耗内存也耗时间。
剩下的都是考验选手的码力了。
int a[1005][1005];
int f[1005][1005];
bool vis[1005][1005];
vector<int> v[1005 * 1005];
struct node {
int y, val;
bool operator < (const node &k) const{
return val > k.val;
}
};
int n, m;
int calc(int x, int y) {
return (x - 1) * m + y;
}
node f_calc(int p) {
int x = p / m;
int y = p % m;
if (y == 0) return {x, m};
else return {x + 1, y};
}
int nex[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int minimumTime(vector<vector<int>>& grid) {
n = grid.size();
m = grid[0].size();
a[1][2] = a[2][1] = 1e9;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
a[i + 1][j + 1] = grid[i][j];
f[i + 1][j + 1] = 1e9;
}
}
if (a[1][2] > 1 && a[2][1] > 1) {
return -1;
}
priority_queue<node> q;
f[1][1] = 0;
q.push({calc(1, 1), 0});
while(!q.empty()) {
int x = f_calc(q.top().y).y, y = f_calc(q.top().y).val;
q.pop();
if (vis[x][y]) {
continue;
}
vis[x][y] = 1;
for (int i = 0; i < 4; i++) {
int tx = x + nex[i][0], ty = y + nex[i][1];
if (tx < 1 || ty < 1 || tx > n || ty > m) continue;
if (tx == 1 && ty == 1) continue;
int last = f[tx][ty];
if (a[tx][ty] <= f[x][y] + 1) {
f[tx][ty] = f[x][y] + 1;
}
else {
f[tx][ty] = (a[tx][ty] - f[x][y]) / 2 * 2 + f[x][y] + 1;
}
if (f[tx][ty] < last) {
q.push({calc(tx, ty), f[tx][ty]});
}
else {
f[tx][ty] = last;
}
}
}
return f[n][m];
}