一. 编程题
1. 第一题 50%
题目:环形数组,长为 n,数组每个位置的值表示大小,一个字符串只包含 ‘R’、’P’ 两种字符,代表数组对应位置为红色 or 紫色。小红和小紫都从数组起点开始一起走,每次走一格,走到红色格子则小红的分数加上对应格子的数值,走到紫色格子则小紫的分数加上对应格子的数值。求问走了 x 步后,小红和小紫的分数。
int main()
{
int n;
cin >> n;
vector
int Q; // 询问次数cin >> Q;for(int q = 0; q < Q; ++q){int x; // 第 x 天后cin >> x;int completeDays = x / n;int remainDays = x % n;long long val1 = completeDays * allVal1;long long val2 = completeDays * allVal2;for(int i = 0; i < remainDays; ++i){if(colors[i] == 'R')val1 += nums[i];else if(colors[i] == 'P')val2 += nums[i];}cout << val1 << " " << val2 << endl;}return 0;
}
- 优化:前缀和、q/n、q%n 之类的优化<a name="rQG5u"></a>## 2. 第二题 95%两人沿三角形边界匀速跑,小红从顶点 A 开始跑,小明从顶点 B 开始走。给定三角形顶点 A、B、C 的坐标,以及小红的速度 v1,小红的方向 d1,小明的速度 v2,小明的速度 d2,问两人第一次相遇的时间,如果不能相遇则输出 -1。(方向为 0 代表:A->B->C->A,方向为 1 代表:A->C->B->A)- 下面的代码过了 95%,应该是忘了一圈内追不上取余之类的操作- 没有考虑两人反向(不是相向),但速度都为 0 的 case```cpp#include <iostream>#include <vector>#include <algorithm>#include <math.h>using namespace std;int main(){int xa, ya, xb, yb, xc, yc;cin >> xa >> ya >> xb >> yb >> xc >> yc;// vector<int> posArr(6);// for(int i = 0; i < 6; ++i)// cin >> posArr[i];int v1, d1, v2, d2;cin >> v1 >> d1 >> v2 >> d2;double t = 0.0;double lenAB = sqrt((xa - xb) * (xa - xb) + (ya - yb) * (ya- yb));double lenBC = sqrt((xb - xc) * (xb - xc) + (yb - yc) * (yb- yc));double lenAC = sqrt((xa - xc) * (xa - xc) + (ya - yc) * (ya- yc));double lenAll = lenAB + lenBC + lenAC;// cout << lenAB << ", " << lenBC << ", " << lenAC << endl;if(d1 == 0 && d2 == 1)t = lenAB / (v1 + v2);else if(d1 == 1 && d2 == 0)t = (lenAC + lenBC) / (v1 +v2);else if(v1 == v2)t = -1;else{if(d1 == 0 && d2 == 0){if(v1 > v2)t = lenAB / (v1 - v2);elset = (lenBC + lenAC) / (v2 - v1);}else if(d1 == 1 && d2 == 1){if(v2 > v1)t = lenAB / (v2 - v1);elset = (lenBC + lenAC) / (v1 - v2);}}cout << t << endl;return 0;}
3. 第三题 88.24%
题目:长为 n 的数组,存储的元素代表数值,长为 n 的字符串代表数组对应位置的颜色(只包含红 R、蓝 B 两种颜色),要求最短的连续区间长度,要满足:区间内红色格子的积 x、区间内蓝色格子的积 y,x 末尾 0 的数量 + y 末尾 0 的数量要大于等于给定的 k
思路:只过了 88.24%
- 滑动窗口
- 末尾 0 的个数,取决于所有乘数的因子中 2 的个数、5 的个数的最小值(参考:[中等] 172. 阶乘后的零)
```cpp
include
include
include
include
using namespace std;
int calCnt5(int num) { int div = 5; int result = 0; while(div <= num) { if(num % div == 0) { ++result; div *= 5; } else break; } return result; }
int calCnt2(int num) { int div = 2; int result = 0; while(div <= num) { if(num % div == 0) { ++result; div *= 2; } else break; } return result; }
int main()
{
int n, k;
cin >> n >> k;
vector
int left = 0;int right = 0;int red2 = 0;int red5 = 0;int blue2 = 0;int blue5 = 0;int result = n;while(right < n){int num = nums[right];++right;int cnt5 = calCnt5(num);if(colors[right - 1] == 'R')red5 = red5 + cnt5;else if(colors[right - 1] == 'B')blue5 = blue5 + cnt5;int cnt2 = calCnt2(num);if(colors[right - 1] == 'R')red2 = red2 + cnt2;else if(colors[right - 1] == 'B')blue2 = blue2 + cnt2;while(min(red2 + red5) + min(blue2 + blue5) >= k){result = min(result, right - left);int deleteNum = nums[left];++left;int dCnt5 = calCnt5(deleteNum);if(colors[left - 1] == 'R')red5 = red5 - dCnt5;else if(colors[left - 1] == 'B')blue5 = blue5 - dCnt5;int dCnt2 = calCnt2(deleteNum);if(colors[left - 1] == 'R')red2 = red2 - dCnt2;else if(colors[left - 1] == 'B')blue2 = blue2 - dCnt2;}}cout << result << endl;return 0;
}
<a name="CLl4Q"></a>## 4. 第四题 0%n 行 m 列的矩阵,存的都是正整数,输入 Q 个 target:- 对于每个 target,如果数组中的元素 = target,则标为红色(若之前已被标记过则仍为红色),求红色连通块的数量。连通块指的是上、下、左、右有一格相邻解法:dfs,示例是对的,但是提交就只能过 0%。。。```cpp#include <iostream>#include <vector>using namespace std;void dfs(vector<vector<int>>& matrix, int row, int col, int target){int n = matrix.size();int m = matrix[0].size();if(row < 0 || row >= n || col < 0 || col >= m || matrix[row][col] != target)return;matrix[row][col] = -1;dfs(matrix, row - 1, col, target);dfs(matrix, row + 1, col, target);dfs(matrix, row, col - 1, target);dfs(matrix, row, col + 1, target);// matrix[row][col] = target;}int main(){int n, m;cin >> n >> m;vector<vector<int>> matrix(n, vector<int>(m));for(int i = 0; i < n; ++i){for(int j = 0; j < m; ++j)cin >> matrix[i][j];}int Q;cin >> Q;for(int q = 0; q < Q; ++q){int target;cin >> target;// cout << "target = " << target << endl;// vector<vector<int>> temp(n, vector<int>(m));// for(int i = 0; i < n; ++i)// {// for(int j = 0; j < m; ++j)// temp[i][j] = matrix[i][j];// }int result = 0;for(int i = 0; i < n; ++i){for(int j = 0; j < m; ++j){if(matrix[i][j] == target){++result;dfs(matrix, i, j, target);// cout << "i = " << i << ", j = " << j << ", matrix[i][j] = " << temp[i][j] << endl;}}}cout << result;if(q != Q - 1)cout << " ";}cout << endl;return 0;}
- 看到有人说用:并查集+map记录同一个数的所有位置
二. 问答题
实现垃圾邮件过滤器:1 百万条的数据集,5 万条是垃圾邮件,95 万条是正常邮件。写下数据处理、特征、模型构建等思路
