ICPC冬令营

冬令营第一天

今天学习的主要内容为函数和结构体,因为网络原因写几道具有代表性的题目。

第一题 Specialized Four-Digit Numbers

题干

Find and list all four-digit numbers in decimal notation that have the property that the sum of its four digits equals the sum of its digits when represented in hexadecimal (base 16) notation and also equals the sum of its digits when represented in duodecimal (base 12) notation.
For example, the number 2991 has the sum of (decimal) digits 2+9+9+1 = 21. Since 2991 = 11728 + 8144 + 9*12 + 3, its duodecimal representation is 189312, and these digits also sum up to 21. But in hexadecimal 2991 is BAF16, and 11+10+15 = 36, so 2991 should be rejected by your program.
The next number (2992), however, has digits that sum to 22 in all three representations (including BB016), so 2992 should be on the listed output. (We don’t want decimal numbers with fewer than four digits – excluding leading zeroes – so that 2992 is the first correct answer.)

题解

题目大意为:从2992开始的四位数的十进制十二进制十六进制每一位的和相等,主要问题是解决将这个数的十进制十二进制和十六进制计算出来。

#include<stdio.h>
#include<math.h>
//Calc函数的第一个参数是想要转换为多少进制,第二个参数是转换的数字
int Calc(int base,int n)
{
    int sum=0;
    for(;n;n/=base)
        sum+=n%base;
    return sum;
}
int main()
{
    int i,a;
    for(i=2992;i<=9999;i++){
        a=Calc(10,i);
        //通过与十进制进行对比,找出与题目相符的数字
        if(a==Calc(12,i)&&a==Calc(16,i))
            printf("%d\n",i);
    }
    return 0;
}

第二题 Simple Addition

题干

在这里插入图片描述

题解

拿到一个数后,可以分解成个位1-9,十位1-9,例如20,从1-9之和为45,同理11-19也为45,再加上10和20,即为45*2+1+2=93,公式为(1 + x) * x) / 2 + n * 45。如要计算10到20的和,则可以计算20和(10-1)的和再相减,即为93-45=48。

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

LL sum(LL n)
{
    LL ans = 0, x;
    while(n) {
        x = n % 10;
        n /= 10;
        ans += ((1 + x) * x) / 2 + n * 45;
    }
    return ans;
}

int main()
{
    LL a, b;
    while(~scanf("%lld%lld", &a, &b) && a >= 0)
        printf("%lld\n", sum(b) - sum(a - 1));

    return 0;
}

第三题 Factorial! You Must be Kidding!!!

题干

在这里插入图片描述

题解

这题有个很坑的地方——n可以为负数。所以需要强行拓展关于阶乘的定义。

factorial(n) = n ∗ factorial(n − 1)

利用题目中给出的这个公式,factorial(0) = 0 ∗ factorial(-1)。
再稍作变形factorial(-1) = factorial(0) / 0,所以-1的阶乘等于∞。继续按照这个思路扩展,factorial(-1) = -1 ∗ factorial(-2),所以-2的阶乘等于-∞。

以此类推,在n为负数的前提下,n如果是奇数答案就是Overflow!,如果是偶数答案就是Underflow!

#include <iostream>
#include <algorithm> 
using namespace std;
 
const long long FACT1 = 10000;
const long long FACT2 = 6227020800;
const int N = 13;
long long fact[N + 1];
 
void init()
{
    fact[0] = 1;
    for(int i=1; i<=N; i++) {
        fact[i] = i * fact[i - 1];
#ifdef DEBUG
        if(fact[i] > FACT2) {
            printf("N=%d\n", i - 1);
            break;
        }
#endif
    }
}
 
int main()
{
    init();
 
    int n;
    while(~scanf("%d", &n))
        if(n > N || (n < 0 && (n * -1 & 1)== 1))
            printf("Overflow!\n");
        else if(fact[n] < FACT1 || (n < 0 && (n * -1 & 1) == 0))
            printf("Underflow!\n");
        else
            printf("%lld\n", fact[n]);
 
    return 0;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值