【独家OD2023C卷真题】20天拿下华为OD笔试【哈希表】2023C-石头剪刀布游戏【欧弟算法】全网注释最详细分类最全的华为OD真题题解

80 篇文章 5 订阅
53 篇文章 2 订阅

题目描述与示例

题目描述

石头剪刀布游戏有 3 种出拳形状:石头、剪刀、布。分别用字母 A , B , C 表示。

游戏规则:

  1. 出拳形状之间的胜负规则如下: A > BB > CC > A">"左边一个字母,表示相对优势形状。右边一个字母,表示相对劣势形状。
  2. 当本场次中有且仅有一种出拳形状优于其它出拳形状,则该形状的玩家是胜利者。否则认为是平局。
  3. 当发生平局,没有赢家。有多个胜利者时,同为赢家。

例如 1: 三个玩家出拳分别是A, B, C ,由于出现三方优势循环(即没有任何一方优于其它出拳者),判断为平局。

例如 2: 三个玩家,出拳分别是 A, B ,出拳 A 的获胜。

例如 3: 三个玩家,出拳全部是 A ,判为平局。

输入描述

在一场游戏中,每个玩家的信息为一行。玩家数量不超过 1000 。每个玩家信息有 2 个字段,用空格隔开:

  1. 玩家 ID:一个仅由英文字母和数字组成的字符串
  2. 出拳形状:以英文大写字母表示, A 、B 、C 形状。 例:
abc1 A
xyz B

解释:玩家 abc1 出拳为石头( A )。玩家 xyz 出拳为剪刀( B )

输出描述

输出为赢家的玩家 ID 列表(一个或多个),每个 ID 一行,按字符串升序排列。如果没有赢家,输出为"NULL"字符串。例如:

abc1

示例一

输入

abc1 A
xyz B

输出

abc1

说明

AB 有优势,abc1 胜出

示例二

输入

abc1 A
xyz A

输出

NULL

说明

没有优胜的出拳形状,平局

示例三

输入

abc1 A
def A
alic A
xyz B

输出

abc1
alic
def

说明

A 为优胜方,有三个赢家。

解题思路

本题就是童年的石头剪刀布游戏,不用想得太复杂。

用一个哈希表记录所有出ABC的人,其中key为字符串ABC中的一种,value为出该种形状的任命所构成的列表。若

  • 哈希表中只存在1种键或者3种键均存在,则说明出现平局,输出"NULL"
  • 哈希表中恰好只存在2种键。若
    • 只存在字符串AB,则逐行输出键A对应的列表升序排列的结果
    • 只存在字符串BC,则逐行输出键B对应的列表升序排列的结果
    • 只存在字符串CA,则逐行输出键C对应的列表升序排列的结果

代码

Python

# 题目:【哈希表】2023C-石头剪刀布游戏
# 分值:100
# 作者:许老师-闭着眼睛学数理化
# 算法:哈希表
# 代码看不懂的地方,请直接在群上提问


from collections import defaultdict

# 构建哈希表,设置默认值为list
dic = defaultdict(list)

# 输入次数未知,使用try-except语句进行处理
while 1:
    try:
        # 输入姓名name和形状k
        name, k = input().split()
        # 将出拳为k的姓名name,记录在dic[k]这个列表中
        dic[k].append(name)
    except:
        break

# 只有1种形状,或3种形状均有,平局,输出NULL
if len(dic) != 2:
    print("NULL")
else:
    # 输出A的情况
    if "A" in dic and "B" in dic:
        ans = dic["A"]
    # 输出B的情况
    elif "B" in dic and "C" in dic:
        ans = dic["B"]
    # 输出C的情况
    else:
        ans = dic["C"]
    # 对ans进行排序后逐行输出
    for name in sorted(ans):
        print(name)

Java

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Map<String, List<String>> dic = new HashMap<>();

        while (true) {
            try {
                String name = scanner.next();
                String k = scanner.next();

                if (!dic.containsKey(k)) {
                    dic.put(k, new ArrayList<>());
                }
                dic.get(k).add(name);
            } catch (Exception e) {
                break;
            }
        }

        if (dic.size() != 2) {
            System.out.println("NULL");
        } else {
            List<String> ans = new ArrayList<>();
            if (dic.containsKey("A") && dic.containsKey("B")) {
                ans = dic.get("A");
            } else if (dic.containsKey("B") && dic.containsKey("C")) {
                ans = dic.get("B");
            } else {
                ans = dic.get("C");
            }

            Collections.sort(ans);
            for (String name : ans) {
                System.out.println(name);
            }
        }
    }
}

C++

#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;

int main() {
    map<string, vector<string>> dic;

    string name, k;
    while (cin >> name >> k) {
        dic[k].push_back(name);
    }

    if (dic.size() != 2) {
        cout << "NULL" << endl;
    } else {
        vector<string> ans;
        if (dic.count("A") && dic.count("B")) {
            ans = dic["A"];
        } else if (dic.count("B") && dic.count("C")) {
            ans = dic["B"];
        } else {
            ans = dic["C"];
        }

        sort(ans.begin(), ans.end());
        for (string name : ans) {
            cout << name << endl;
        }
    }

    return 0;
}

时空复杂度

时间复杂度:O(NlogN)。排序所需的时间复杂度

空间复杂度:O(N)。哈希表所需空间。


华为OD算法/大厂面试高频题算法练习冲刺训练

  • 华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务100+同学成功上岸!

  • 课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化

  • 每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!

  • 60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁

  • 可上全网独家的欧弟OJ系统练习华子OD、大厂真题

  • 可查看链接 大厂真题汇总 & OD真题汇总(持续更新)

  • 绿色聊天软件戳 od1336了解更多

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
题目描述: 给定一个整数数组nums和一个整数k,编写一个函数来判断数组中是否存在 k 个不同的索引i、j、l和m,使得nums[i] + nums[j] == nums[l] + nums[m]。如果存在,返回true;否则,返回false。 解题思路: 首先,我们可以使用4个for循环来遍历所有可能的索引组合,然后判断它们对应元素的和是否相等。但是这种方法的时间复杂度为O(n^4),显然效率很低。因此,我们可以优化思路,使用哈希表来存储数组元素的和及其对应的索引,然后遍历所有可能的组合,判断是否存在相等的和。 具体步骤: 1. 创建一个HashMap<Integer, List<int[]>>来存储和及其对应的索引组合; 2. 遍历数组nums的所有可能组合,计算两个元素的和,并将和及其对应的索引组合存入HashMap中; 3. 再次遍历数组nums,对于每个元素,查找是否存在k-1个不同的索引对应的和在HashMap中,如果存在,则返回true; 4. 遍历结束后若未找到满足条件的索引组合,则返回false。 代码实现: ```java public static boolean checkKSum(int[] nums, int k) { Map<Integer, List<int[]>> map = new HashMap<>(); for (int i = 0; i < nums.length; i++) { for (int j = i + 1; j < nums.length; j++) { int sum = nums[i] + nums[j]; if (!map.containsKey(sum)) { map.put(sum, new ArrayList<>()); } map.get(sum).add(new int[]{i, j}); } } for (int i = 0; i < nums.length; i++) { for (int j = i + 1; j < nums.length; j++) { int target = nums[i] + nums[j]; if (map.containsKey(target)) { List<int[]> list = map.get(target); for (int[] pair : list) { if (pair[0] != i && pair[1] != i && pair[0] != j && pair[1] != j) { return true; } } } } } return false; } ``` 以上就是对2023华为od机试真题java【k数之和】的回答,希望对您有所帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值