专栏文章

题解:P12681 【MX-J15-T1】叉叉学习数据类型

P12681题解参与者 2已保存评论 1

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
1 条
当前快照
1 份
快照标识符
@mip5r28p
此快照首次捕获于
2025/12/03 06:36
3 个月前
此快照最后确认于
2025/12/03 06:36
3 个月前
查看原文

题意

给一个整数 nn,求这个数在哪一个数据类型的取值范围内。

思路

由于范围中给出 n10100|n| \le 10^{100},因此需要用高精度存数字。
随后,将 nn 和各个数据类型的范围边界比较,若在范围内则这个数据类型可以存储 nn
以下给出各数据类型的范围:
  • int: 2,147,483,648n2,147,483,647-2,147,483,648 \le n \le 2,147,483,647
  • unsigned int: 0n4,294,967,2950 \le n \le 4,294,967,295
  • long long: 9,223,372,036,854,775,808n9,223,372,036,854,775,807-9,223,372,036,854,775,808 \le n \le 9,223,372,036,854,775,807
  • unsigned long long: 0n18,446,744,073,709,551,6160 \le n \le 18,446,744,073,709,551,616
string 可以存储任意长度的数字,因此对于任意的 nnstring 都应当输出。
然后就是比较大小的问题。对于两个高精度数 aabb,若 aa 的位数大于 bb 的位数,则 a>ba > b;若 aa 的位数小于 bb 的位数。则 a<ba < b
aa 的位数等于 bb 的位数,那么从低位起遍历,记 aabb 从低位开始第 ii 个数分别为 aia_ibib_i,只要遍历到 ai>bia_i > b_i,则 a>ba > b;只要遍历到 ai<bia_i < b_i,则 a<ba < b;若所有数字都相等,则 a=ba = b
由于考虑负数,所以对于两个异号的数而言,正数大于负数。对于两个负数而言,因为数的绝对值越大反而越小,所以将以上的所有条件的不等号改变方向即可。

Code

CPP
#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
struct bignum{
    int num[105], len, type;
    bignum(){
        len = 1; // 长度
        type = 0; // 正负,初始为 0
    }
    int &operator[](int i){
        return num[i];
    } // 定义 a[i] = a.num[i] 以便访问
    void strnum(string str){ // 字符串转高精度
        if(str == "0"){ // 为 0
            len = 1;
            type = 0;
            num[1] = 0;
            return ;
        }
        if(str.front() == '-') type = -1; // 有负号,正负改为负数
        else type = 1; // 没负号,为正数
        for(int i = 0;i < str.length();i++){
            if(!isdigit(str[i])) continue;
            num[str.length() - i] = str[i] - '0';
        } // 存储数字
        len = str.length();
        if(type == -1) len--;
        return ;
    }
    friend bool operator >(bignum a, bignum b){ // 定义大于号
        if(a.type < b.type) return false;
        if(a.type > b.type) return true;
        if(a.type == b.type && a.type == 0) return false;
        if((a.len > b.len && a.type == 1) || (a.len < b.len && a.type == -1)) return true;
        if((a.len < b.len && a.type == 1) || (a.len > b.len && a.type == -1)) return false;
        for(int i = a.len;i >= 1;i--){
            if((a[i] < b[i] && a.type == 1) || (a[i] > b[i] && a.type == -1)) return false;
            if((a[i] > b[i] && a.type == 1) || (a[i] < b[i] && a.type == -1)) return true;
        }
        return false;
    }
};
bignum retnum(string str){
    bignum res;
    res.strnum(str);
    return res;
} // 将字符串转换为高精度数
bignum n;
string inpn;
int main()
{
    cin >> inpn;
    n.strnum(inpn);
    // 正常的分支结构,开始比较
    if(n > retnum("-2147483649") && retnum("2147483648") > n) puts("int");
    if(n > retnum("-1") && retnum("4294967296") > n) puts("unsigned int");
    if(n > retnum("-9223372036854775809") && retnum("9223372036854775808") > n) puts("long long");
    if(n > retnum("-1") && retnum("18446744073709551616") > n) puts("unsigned long long");
    puts("string"); // 任何数字都可用 string 存储,因此最后输出 string
    return 0; // 结束 (。・ω・。)
}

评论

1 条评论,欢迎与作者交流。

正在加载评论...