两道关于函数模板的c++习题

img

img


第一题b选项2.5不是int型的啊
第二题e选项为什么不行?求指点 (*꒦ິ⌓꒦ີ)

img


那为什么这个e可以

第一题,2.5在数组初始化时强制转为整数
第二题,传入的两个类型要相同

  • 这篇博客: 第十三届蓝桥杯省赛C++B组 真题题解(详细讲解+代码分析)看这篇就够了~~~中的 E.X 进制减法 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 题目描述
    进制规定了数字在数位上逢几进一。
    X 进制是一种很神奇的进制,因为其每一数位的进制并不固定!
    例如说某种 X 进制数,最低数位为二进制,第二数位为十进制,第三数位为八进制,则 X 进制数 321 转换为十进制数为 65。
    现在有两个 X 进制表示的整数 A 和 B,但是其具体每一数位的进制还不确定,只知道 A 和 B 是同一进制规则,且每一数位最高为 N 进制,最低为二进制。
    请你算出 A−B 的结果最小可能是多少。
    请注意,你需要保证 A 和 B 在 X 进制下都是合法的,即每一数位上的数字要小于其进制。

    输入格式
    第一行一个正整数 N,含义如题面所述。
    第二行一个正整数 Ma,表示 X 进制数 A 的位数。
    第三行 Ma 个用空格分开的整数,表示 X 进制数 A 按从高位到低位顺序各个数位上的数字在十进制下的表示。
    第四行一个正整数 Mb,表示 X 进制数 B 的位数。
    第五行 Mb 个用空格分开的整数,表示 X 进制数 B 按从高位到低位顺序各个数位上的数字在十进制下的表示。
    请注意,输入中的所有数字都是十进制的。

    输出格式
    输出一行一个整数,表示 X 进制数 A−B 的结果的最小可能值转换为十进制后再模 1000000007 的结果。

    数据范围
    对于 30% 的数据,N≤10;Ma,Mb≤8,
    对于 100% 的数据,2≤N≤1000;1≤Ma,Mb≤100000;A≥B。

    输入样例:

    11
    3
    10 4 0
    3
    1 2 0
    

    输出样例:

    94
    

    样例解释
    当进制为:最低位 2 进制,第二数位 5 进制,第三数位 11 进制时,减法得到的差最小。
    此时 A 在十进制下是 108,B 在十进制下是 14,差值是 94。

    思路

    推出进制计算方式:每一位数字,乘以该数字数位后所有进制数,求和即为结果
    欲使A-B最小,只需使得各位数字取得合法范围内的最小进制即可,具体做法就是对A和B中相同数位的数字取xmax = max(a[i], b[i]),该位的合法最小进制即为max(xmax + 1, 2)
    因为最小进制不能小于2;而对于X进制的数来说,合法的最大数字是X-1,例如8进制中最大数字是7,二进制中最大数字是1。
    而求A和B的值,只需要再开一个数组存储各位数字的实际权重,再将各位数字和对应的权重相乘后相加即可。
    需要注意的是这个题数据比较大,需要多次取模,特别是最后计算最终结果的时候,应(A - B + mod) % mod,否则可能A本来比B大,但是取模后比B小,这样A-B可能会出现负值。

    AC代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e5+10,mod=1000000007;
    ll a[N],b[N],w[N],mul[N]; 
    ll A,B;
    //a存储A各位数字,b存储B各位数字,w存储各位的进制,mul存储各位数字的实际权重
    int main(){
        int n,ma,mb;
        cin>>n;  // 最大进制
        cin>>ma;
        for(int i=ma;i>=1;i--) cin>>a[i];
        cin>>mb;
        for(int i=mb;i>=1;i--) cin>>b[i];
        // 确定各位进制 w[i]
        int maxx=max(ma,mb); // A B 中最大的位数
        for(int i=maxx;i>=1;i--){
            int tmax=max(a[i],b[i]);
            w[i]=max(2,tmax + 1);
        }
        // 计算权重
        mul[1]=1;
        for(int i=2;i<=maxx;i++){
            mul[i]=w[i-1]*mul[i-1]%mod;
        }
        // 计算A
        for(int i=ma;i>=1;i--){
            A=(A+a[i]*mul[i])%mod;
        }
        // 计算B
        for(int i=mb;i>=1;i--){
            B=(B+b[i]*mul[i])%mod;
        }
        // A - B
        cout<<(A-B+mod)%mod<<endl;
        return 0;
    }
    
  • 以下回答由chatgpt基于相关博客总结生成:
    1. 关于第一题b选项的问题,既可以改为double类型,也可以选用下取整或四舍五入的方式将计算结果转换成int类型。假设选用下取整的方式,可以先将结果转换为int类型,再对其下取整。代码如下:
    double ans = ...; // 之前计算出的结果
    int res = static_cast<int>(ans); // static_cast 用于进行静态类型转换,一般不会执行运行时类型检查
    if (ans < res) // 如果计算结果小数位上的数字不为 0,那么需要下取整
        res--; // 直接将小数部分直接去掉,即下取整
    return res; // 返回下取整后的结果
    
    1. 关于第二题e选项的问题,可以通过提升变量的类型来解决。e选项的计算结果需要是unsigned long long类型,而int类型的最大值只有2的31次方减1,因此需要提升变量的类型避免溢出。代码如下:
    template <typename A, typename B>
    decltype(A{} + B{}) demo2(A a, B b)
    {
        // static_cast 用于进行静态类型转换,一般不会执行运行时类型检查
        return static_cast<decltype(A{} + B{})> (a + b);
    }