2022-04-08美团笔试练题

两个字符串,忽略顺序,是否相同,即是否包含相同的字符,对应字符的数量也相同

"hello"和"olleh"相同。
思路:位运算,0异或0=0,0异或1=1,所以ans初始化为0,任何数和自己异或结果为0,这样用0异或两个字符串的每个字符就可。O(n)

    bool match(string str1, string str2) {
        int n = str1.size();
        int n2 = str2.size();
        if (n != n2) return false;
        int ans = 0;
        for (int i = 0; i < n; ++i) {
            ans ^= str1[i];
            ans ^= str2[i];
        }
        return ans == 0;
    }

    int main(){
        string str1 = "hello";
        string str2 = "heoll";
        cout << match(str1, str2);
        return 0;
    }

此解答有误!!,没考虑str1和str2内部异或结果为0的情况。

小美斗恶龙

时间限制:3000MS

内存限制:1048576KB

题目描述: 小美得到了一款游戏——斗龙。小美拥有两个技能,每个技能都能秒杀掉一条龙,但是要付出相应的MP值,第一个技能需要c1点MP值,第二个技能需要c2点MP值。只要MP足够,小美可以使用无限次技能。

小美即将遇到 n 条龙,如果不使用技能,她和第 i 条龙的战斗结果是T或者F,而如果使用任何一个技能战斗结果都是T。T表示小美成功打败龙,而F表示小美被龙打败。如果小美被龙连续打败三次,那小美就会输掉游戏。请你帮忙计算小美最少需要多少点 MP才能通关。

输入描述:

第一行三个数 n, c1, c2。(1 ≤ n ≤ 100000,1 ≤ c1, c2 ≤ 1000000000)。

第二行 n 个字符,第 i 个字符 si 代表小美与第 i 场战斗的结果。si 是 T 代表小美打败龙,si 是 F 代表小美被龙打败。

输出描述:

输出一个数,代表小美最少需要的MP值。

样例输入:

10 7 3
FTFFFTFFFF
样例输出:
6

提示:
小美可以在第3场战斗、第8场战斗中使用第二个技能,需要耗费3×2=6点MP。

    int main(){
        int n;
        long c1, c2;
        cin >> n >> c1 >> c2;
        string s;
        cin >> s;
        long mp = min(c1, c2);
        int n1 = s.size();//本题不需要,在n处会输入决定
        int freq = 0;//连续F次数,遇到T清0,连续第三次F,用技能然后清0
        long mpsum = 0;
        for (int i = 0; i < n1; ++i) {
            if (s[i] == 'T') {
                freq = 0;
                continue;
            }
            else {
                if (freq == 2) {
                    mpsum += mp;
                    freq = 0;
                }
                else {
                    freq += 1;
                }
            }
        }
        cout<<mpsum;
        return 0;
    }

小美中奖啦

持续补充

小美记数字

三、小美记数字
小美的记忆力超级棒,小团决定来考一考小美。小团给了小美 n 个数,从左到右排成一行,给了1 分钟让小美记住。然后小团会询问 m 次,每次都问数 x 第一次出现的位置和最后一次出现的位置,若数 x 没出现过,那么回答 0 即可。小美的记忆力好,但是 1 分钟记住这么多数实在是太难了,请你帮帮小美,完成这次不可能的挑战。

输入描述
第一行两个数 n, m。(1 ≤ n, m ≤ 50000)。

第二行 n 个数,第 i 个数是 ai。(1 ≤ ai ≤ 1000000000)。

接下来 m 行,每行一个数 x (1 ≤ x ≤ 1000000000),代表一次询问。

输出描述
输出 m 行,若数 x 出现过,输出数 x 第一次出现的位置和最后一次出现的位置。若数 x 没出现过,输出 0。

样例输入
6 4
2 3 1 2 3 3
1
2
3
4
样例输出
3 3
1 4
2 6
0

提示
1 出现的位置有 3,所以答案为 3 3。
2 出现的位置有 1, 4,所以答案为 1 4。
3 出现的位置有 2, 5, 6,所以答案为 2 6。
4 没有出现过,所以答案为 0。

    int main(){
        int m, n;
        cin >> n >> m;
        vector<long> v(n);
        for (int i = 0; i < n; ++i) {
            cin >> v[i];
        }
        unordered_map<long, int> mfirst;//存第一次出现的下标
        unordered_map<long, int> mlast;//存最后一次出现的下标
        for (int i = 0; i < n; ++i) {
            if (mfirst.find(v[i]) == mfirst.end()) {
                mfirst[v[i]] = i+1;//位置是下标+1
                mlast[v[i]] = i+1;
            }
            else mlast[v[i]] = i+1;
        }
        for (int i = 0; i < m; ++i) {
            int q;
            cin >> q;
            if (mfirst.find(q) == mfirst.end()) {
                cout << 0 << endl;
            }
            else {
                cout << mfirst[q] << " " << mlast[q] << endl;
            }
        }
        return 0;
    }

奶茶

在这里插入图片描述
这个样例就是说3个人,把5杯奶茶分三段,5+8一个人喝,(5+8)/4向上取整是4,(3+10)/4也是4,7是2,取最大。

int minTime = INT_MAX;
    void findTime(vector<int> v, int begin, int people, int time, double c) {
        if (people == 1) {//最后一个人从begin喝到完
            double sum = 0;
            for (int i = begin; i < v.size(); ++i) {
                sum += v[i];
            }
            time = max(time, int(ceil(sum / c)));//当前方案用的时间
            minTime = min(minTime, time);//记录一个最小时间
        }
        else {//剩余不止1人能分配
            for (int i = begin; i < v.size(); ++i) {//i到结束中间切下来一人份,就是j的范围
                double sum = 0;
                for (int j = begin; j <= i; ++j) {//这个人要喝掉sum分量奶茶
                    sum += v[j];
                }
                findTime(v, i + 1, people - 1, max(time, int(ceil(sum / c))), c);//切下来一人份以后,剩下的时长
            }
        }
    }
    int main(){
        int n, m;
        double c;
        cin >> n >> m >> c;
        vector<int> v(n, 0);
        for (int i = 0; i < n; ++i) {
            cin>>v[i];
        }
        findTime(v, 0, m, 0, c);
        cout << minTime;
        return 0;
    }

值日

在这里插入图片描述

    int main(){
        int n, m;
        cin >> n >> m;
        vector<vector<int>> v(n,vector<int>(n, 0));
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                cin >> v[i][j];
            }
        }
        //cin >> n >> m;
        int id = 0;
        int a1 = 1, a2 = 2;
        for (int k = 0; k < m - 2;++k) {//更新m-2次
            id = v[a2 - 1][a1 - 1];//注意它下标是从1起的就行了
            a1 = a2;
            a2 = id;
        }
        if (m == 1)cout << 1;
        if (m == 2)cout << 2;
        else cout << id;
        return 0;
    }

在这里插入图片描述

    int main(){
        string str1, str2;
        cin >> str1;
        cin >> str2;
        string str1_copy = str1;//复制string1
        int n = str2.size();
        int sum = 0;
        for (int i = 0; i < n; ++i) {
            int n2 = str1.size();
            for (int j = 0; j < n2; ++j) {
                if (str2[i] == str1[j]) {
                    sum += j;
                    if (j != n2 - 1) {
                        str1 = str1.substr(j + 1) + str1_copy;//流剩余部分加上一个string1
                    }
                    else {
                        str1 = str1_copy;
                    }
                    break;
                }
            }
        }
        cout << sum;
        
        return 0;
    }
    //abcdefghijklmnopqrstuvwxyz

寻找数字

在这里插入图片描述

    int main(){
        string s;
        cin >> s;
        vector<int> v;
        int num = 0;
        for (int i = 0; i < s.size(); ++i) {
            if (isdigit(s[i])) {
                num = num * 10 + int(s[i] - '0');
                if (i == s.size() - 1) {//如果扫到最后一个数,也要存进v
                    v.push_back(num);
                }
            }
            else {//遇到非数字,把已有非0数字存进v
                if (num != 0) {
                    v.push_back(num);
                    num = 0;
                }
                continue;
            }
        }
        sort(v.begin(), v.end());//排序
        for (auto c : v) {
            cout << c << endl;
        }
        return 0;
    }

蚂蚁上树

做一遍没有上司的舞会,掌握树形dp,牛客dp专项有树形dp的题。
https://www.nowcoder.com/discuss/613226?source_id=profile_create_nctrack&channel=-1

数数

https://blog.csdn.net/qq_44745063/article/details/114782323

多重集合

溶液

https://blog.csdn.net/econe_wei/article/details/115037497

http://dljz.nicethemes.cn/news/show-32449.html

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值