九坤投资专场竞赛 题解

1. 可以读通讯稿的组数

在这里插入图片描述

经典的哈希做法代替双指针的题。我们可以将原式进行移项,将自身与自身的镜像值相减(这里的差值我们记作dist)。
那么问题就变成了:自身与自身的镜像值相减 相等的对数,那么很显然就是 C n 2 = n ∗ ( n − 1 ) 2 C_n^2 = \frac{ n * (n-1) } {2} Cn2=2n(n1)
所以我们只需要去使用哈希表记录dist 的个数,最后使用组合数计算一下即可。

class Solution {
public:
    using ll = long long;
    static const int mod = 1e9+7;
    int numberOfPairs(vector<int>& nums) {
        unordered_map<ll, ll> mp;
        ll ans = 0;
        for(auto c : nums){
            string r = to_string(c);
            reverse(r.begin(), r.end());
            int cur = c, rev = stoi(r);
            mp[cur-rev] += 1;
        }
        for(auto &[k, v] : mp){
            ans += 1LL * v * (v-1) / 2;
        }
        return ans % mod;
    }
};

2. 池塘计数

在这里插入图片描述

这一题呢就是一个经典的搜索加标记了:没遇见一块积水,则以改位置展开搜索,标记所有与其相连的积水即可。

class Solution {
public:
    int lakeCount(vector<string>& field) {
        const int N = 110;
        const int dx[] = {-1, -1, -1, 0, 0, 1, 1, 1};
        const int dy[] = {1, 0, -1, 1, -1, 1, 0, -1};
        int vis[N][N], ans = 0;
        memset(vis, 0, sizeof(vis));
        int n = field.size(), m = field[0].size();
        function<void(int, int)> dfs = [&](int x, int y) -> void {
            for(int i = 0; i < 8; i++){
                int nx = x + dx[i], ny = y + dy[i];
                if(nx < 0 || nx >= n || ny < 0 || ny >= m || vis[nx][ny] || field[nx][ny] == '.') continue;
                vis[nx][ny] = 1;
                dfs(nx, ny);
            }
        };
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                 if(field[i][j] == 'W' && vis[i][j] == 0){
                     dfs(i, j);
                     ans += 1;
                 }
            }
        }
        return ans;
    }
};

3. 数字默契考验

在这里插入图片描述
容易发现,若有解,即最小相等的数字则为所有数的 LCM (最小公倍数),所以我们可以先求出LCM,然后判断每个数(记为C)增大的倍数dist = LCM / C,如果dist 可以被分解为 P个2与Q个3的乘积, 即: d i s t = 2 P ∗ 3 Q ( P , Q ≥ 0 ) dist = 2 ^ P * 3 ^ Q (P, Q \ge 0) dist=2P3Q(P,Q0),则说明该数可以通过乘 2 何乘 3 增大 直至等于 LCM,否则说明存在一个数不满足条件,则返回 -1,表示无解。
tips: 求解LCM 和 dist 的时候记得都开long long 否则 可能溢出,导致结果不正确

class Solution {
public:
    using ll = long long;
    int minOperations(vector<int>& numbers) {
        ll n = numbers.size(), ans = 0, lcm = 1;
        for(auto &c : numbers) lcm = ::std::lcm(lcm, 1LL * c);
        for(auto c : numbers) {
            ll dist = lcm / c, cnt = 0;
            while(dist % 2 == 0){
                dist /= 2;
                cnt++;
            }
            while(dist % 3 == 0){
                dist /= 3;
                cnt++;
            }
            if(dist == 1) ans += cnt;
            else return -1;
        }
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值