冬令营第一天
今天学习的主要内容为函数和结构体,因为网络原因写几道具有代表性的题目。
第一题 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;
}