Coding Practice,48天强训(23)

Topic 1:打怪(回合数与刀数、先后手关系)

登录—专业IT笔试面试备考平台_牛客网

#include <bits/stdc++.h>
using namespace std;

int main() 
{
    int t;
    cin >> t;
    while (t--) 
    {
        int h, a, H, A;
        cin >> h >> a >> H >> A;
        int roundM = (H + a - 1) / a; //勇士打掉1只毛球的回合数 向上取整等价ceil(H / a)
        if (A <= 0 || roundM - 1 <= 0) cout << -1 << endl;
        else 
        {   
            int x = (h - 1) / ((roundM - 1) * A);//(h-1)保证勇士打完最后一只时血量严格>0
            cout << x << endl;
        }
    }
    return 0;
}

这题主要的难点在于勇士打完最后一只毛球的边界计算,如intx = 8 / 2,看似勇士能够打4只毛球,但当打完第4只时勇士的血量已经归0,也就意味着最后被计算的那只毛球勇士是没办法打死的,在完成整个击杀动作后,勇士的血量必须严格>0,才能合法的计入击杀数,所以(8 - 1) / 2 = 3,最后一次攻击的过程由于向下取整的特性被垫掉了(勇士在过程中已经死亡,无法完成击杀动作),最后只能打3只,这才是合理的;

Topic 2:字符串的分类(哈希、排序)

字符串分类_牛客笔试题_牛客网

我们说两个字符串是“字母异位词”(Anagrams),比如:"abcd" 和 "dcba" 是异位词,因为都是由 a, b, c, d 组成的;"abc" 和 "cba" 也是异位词;但是 "abc" 和 "abcc" 就不是异位词。

只要一个字符串可以通过“任意交换字符位置”得到另一个,那么它们就是同一类。这跟你怎么交换、交换多少次无关,也可以说,只要两个字符串的组成是一样的,它们就是一类

怎么快速判断两个字符串是不是同一类?

最简单的方法是把字符串里的字符排序,然后比较排序后的结果。比如:"abcd" 排序后是 "abcd";"dcba" 排序后是 "abcd";"acbd" 排序后是 "abcd",根据ASCII码值排列后,如果字符数量相同,就可以视作一类

#include <bits/stdc++.h>

using namespace std;

int main() 
{
    int N;              // 输入的字符串个数
    cin >> N;

    set<string> se;  // 用来存放每个“类别”的代表字符串(排序后的字符串)

    for (int i = 0; i < N; ++i) 
    {
        string s;
        cin >> s;
        sort(s.begin(), s.end()); // 根据ASCII排序
        se.insert(s);     // 放入集合中(集合自动去重)
    }

    cout << se.size() << endl;  // 输出有多少个不同的类别
    return 0;
}

代码很简单,主要考察对set容器的理解;

Topic 3:城市群数量

城市群数量_牛客题霸_牛客网

图论,主要考察图的遍历

class Solution 
{
public:
    bool vis[210] = { 0 }; // 标记数组,vis[i] = true 表示节点 i 已被访问

    int citys(vector<vector<int>>& m) 
    {
        int res = 0; // 初始化城市群数量为 0
        int n = m.size(); // 节点数量

        for(int i = 0; i < n ; ++i) // 遍历所有节点
        {
            if(!vis[i]) // 如果节点 i 未被访问过
            {
                res++; // 发现一个新的城市群
                dfs(m, i); // 从节点 i 开始 DFS,标记所有连通节点
            }
        }
        return res; // 返回城市群数量
    }

    void dfs(vector<vector<int>>& m, int pos)
    {
        vis[pos] = true; // 标记当前节点为已访问
        for(int i = 0; i < m.size() ; ++i) // 遍历所有节点
        {
            // 如果节点 i 未被访问且与当前节点 pos 相连
            if(!vis[i] && m[pos][i]) dfs(m, i); // 递归访问节点 i
        }
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值