题目链接

数字的情绪

题目描述

给定一个正整数 ,设其十进制表示中所有出现过的数字构成的集合为 。我们根据以下规则判断 的情绪:

  • 开心数 (Happy): 若存在某些 使得 。记作 H

  • 沮丧数 (Sad): 若对所有 均有 。记作 S

  • 极棒数 (Great): 若对所有 均有 。记作 G

特别地,题目规定对于任意正整数 ,均有

解题思路

根据您提供的正确代码,本题的评判逻辑可以被一种更简洁的方式统一起来。其核心思想是遍历数字 的每一位(包括重复位),并根据一个统一的规则来计数。

  1. 统一判断规则:我们不再需要对是否包含 0 进行复杂的分类讨论。而是为每一位数字 定义一个统一的“通过”条件:

    • 该位数字是 0 ()。
    • 或者,该位数字能整除 ()。

    只要满足这两个条件之一,我们就认为该数位是“成功的”。这种逻辑巧妙地利用了 or 的短路特性,将 的特殊性(不能做除数)和它在题目中的角色(作为“成功”条件之一)完美地结合在了一起。

  2. 遍历与计数:为了处理包括重复位在内的每一位数字,我们应将输入的数字 当作字符串来处理。然后遍历这个字符串,对每一个字符转换成的数字应用上述的“统一判断规则”。我们用一个计数器 来记录“成功”的数位的总数。

  3. 最终分类:遍历结束后,比较“成功”的数位数量 和数字 的总位数

    • 如果 ,说明所有数位都“成功”了,因此是“极棒数”(G)。
    • 如果 ,说明没有一个数位“成功”(这意味着数中没有0,且所有非零位都不能整除),因此是“沮丧数”(S)。
    • 如果 ,说明部分数位“成功”,部分不成功,因此是“开心数”(H)。

这种方法不仅逻辑清晰,而且实现起来也更为直接。

代码

#include <iostream>
#include <string>
#include <vector>

using namespace std;

void solve() {
    string line;
    cin >> line;
    long long n = stoll(line);
    
    int count = 0;
    for (char ch : line) {
        int digit = ch - '0';
        if (digit == 0 || n % digit == 0) {
            count++;
        }
    }
    
    if (count == line.length()) {
        cout << "G" << endl;
    } else if (count == 0) {
        cout << "S" << endl;
    } else {
        cout << "H" << endl;
    }
}

int main() {
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int t = sc.nextInt();
        while (t-- > 0) {
            String line = sc.next();
            long n = Long.parseLong(line);
            
            int count = 0;
            for (char ch : line.toCharArray()) {
                int digit = ch - '0';
                if (digit == 0 || n % digit == 0) {
                    count++;
                }
            }
            
            if (count == line.length()) {
                System.out.println("G");
            } else if (count == 0) {
                System.out.println("S");
            } else {
                System.out.println("H");
            }
        }
    }
}
import sys

queryTimes = int(sys.stdin.readline())

for i in range(queryTimes):
    line = sys.stdin.readline().strip()
    n = int(line)
    
    count = 0
    for ch in line: 
        digit = int(ch)
        if(digit == 0 or n % digit == 0):
            count += 1
            
    if(count == len(line)):
        print("G")
    elif(count == 0):
        print("S")
    else:
        print("H")

算法及复杂度

  • 算法:模拟、字符串处理
  • 时间复杂度:对于一个整数 ,其位数为 。我们需要遍历每一位,所以对于每组测试数据,时间复杂度为
  • 空间复杂度:需要存储输入的字符串,其长度为 ,所以空间复杂度为