1. 可以读通讯稿的组数
校运动会上,所有参赛同学身上都贴有他的参赛号码。某班参赛同学的号码记于数组 nums 中。假定反转后的号码称为原数字的「镜像号码」。如果 两位同学 满足条件:镜像号码 A + 原号码 B = 镜像号码 B + 原号码 A,则这两位同学可以到广播站兑换一次读通讯稿的机会,为同班同学加油助威。请返回所有参赛同学可以组成的可以读通讯稿的组数,并将结果对10^9+7取余。
注意:
- 镜像号码中如存在前置零,则忽略前置零。
- 同一位同学可有多次兑换机会。
示例 1:
输入:
nums = [17,28,39,71]输出:
3解释:
共有三对同学,分别为 [17,28]、[17,39]、[28,39]。其中:
第一对同学:17 + 82 = 71 + 28;
第二对同学:17 + 93 = 71 + 39;
第三对同学:28 + 93 = 82 + 39。
示例 2:
输入:
nums = [71, 60]输出:
1解释:
共有一对同学,为 [71, 60]。
因为 71 + 6 = 17 + 60,此处 60 的镜像号码为 6,前导零被忽略。
提示:
0 <= nums.length <= 10^60 <= nums[i] <= 10^9
题解: 哈希表
class Solution {
public:
int numberOfPairs(vector<int>& nums) {
int n = nums.size();
vector<int> f;
for(auto x : nums){
int t = x, s =0;
while(t){
s = s*10+t%10;
t/=10;
}
f.push_back(s);
}
unordered_map<int, int> hash;
for(int i=0; i<n; i++){
hash[f[i]-nums[i]]++;
}
long res = 0, mod = 1e9+7;
for(auto [k, v] : hash){
res += v%mod*(v-1)/2;
}
return res%mod;
}
};
2. 池塘计数
最近的降雨,使田地中的一些地方出现了积水,field[i][j] 表示田地第 i 行 j 列的位置有:
- 若为
W, 表示该位置为积水; - 若为
., 表示该位置为旱地。
已知一些相邻的积水形成了若干个池塘,若以 W 为中心的八个方向相邻积水视为同一片池塘。
请返回田地中池塘的数量。
示例 1:
输入:
field = [".....W",".W..W.","....W.",".W....","W.WWW.",".W...."]输出:
3解释:如下图所示,共有 3 个池塘:
示例 2:
输入:
field = ["W....W",".W..W.","..W.W.","W..W..","W.W...",".W...."]输出:
1解释:如下图所示,共有 1 个池塘:
提示:
1 <= field.length, field[i].length <= 100field中仅包含W和.
题解: 搜索 BFS/DFS
class Solution {
public:
void dfs(vector<string>&g, int x, int y, int n, int m){
if(x < 0 || x>=n || y <0 || y>=m){
return;
}
if(g[x][y] == '.'){
return;
}
g[x][y] = '.';
dfs(g, x-1, y, n, m);
dfs(g, x, y+1, n, m);
dfs(g, x+1, y, n, m);
dfs(g, x, y-1, n, m);
dfs(g, x-1, y+1, n, m);
dfs(g, x+1, y+1, n, m);
dfs(g, x+1, y-1, n, m);
dfs(g, x-1, y-1, n, m);
}
int lakeCount(vector<string>& g) {
int n = g.size(), m = g[0].size();
int res = 0;
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
if(g[i][j] == 'W'){
res++;
dfs(g, i, j, n, m);
}
}
}
return res;
}
};
3. 数字默契考验
某数学兴趣小组有 N 位同学,编号为 0 ~ N-1,老师提议举行一个数字默契小测试:首先每位同学想出一个数字,按同学编号存于数组 numbers。每位同学可以选择将自己的数字进行放大操作,每次在以下操作中任选一种(放大操作不限次数,可以不操作):
- 将自己的数字乘以 2
- 将自己的数字乘以 3
若最终所有同学可以通过操作得到相等数字,则返回所有同学的最少操作次数总数;否则请返回 -1。
示例 1:
输入:numbers = [50, 75, 100]
输出:5
解释:
numbers[0] * 2 * 3 = 300 操作两次;
numbers[1] * 2 * 2 = 300 操作两次;
numbers[2] * 3 = 300 操作一次。共计操作五次。
示例 2:
输入:numbers = [10, 14]
输出:-1
解释:无法通过操作得到相同数字。
提示:
1 <= numbers.length <= 10^51 <= numbers[i] <= 10^9
题解: 最小公倍数
class Solution {
public:
int minOperations(vector<int>& nums) {
int n = nums.size();
long long s = 1;
for(int i=0; i<n; i++){
s = s/__gcd(s, (long long)nums[i]) * (long long)nums[i];
}
int res = 0;
for(int i=0; i<n; i++){
long diff = s/nums[i];
if(diff%2 == 0){
while(diff%2 == 0) diff /=2, res++;
}
if(diff%3 == 0){
while(diff%3 == 0) diff /=3, res++;
}
if(diff != 1) return -1;
}
return res;
}
};
第四题不知道怎么做😭。。。