1.平方和
问题描述:
小明对数位中含有 2、0、1、9 的数字很感兴趣,在 1 到 40 中这样的数包括 1、2、9、10 至 32、39 和 40,共 28 个,他们的和是 574,平方和是 14362。注意,平方和是指将每个数分别平方后求和。
请问,在 1 到 2019 中,所有这样的数的平方和是多少?
分析:
首先可以根据题目提供的例子来很快理解下
范围 | 符合条件的数字 |
---|---|
1 ~ 10 | 1, 2, 9, 10 |
11 ~ 20 | 所有此范围内数字(10个) |
21 ~ 30 | 所有此范围内数字(10个) |
31 ~ 40 | 31, 32, 39, 40 |
只要数字中包含2 0 1 9这四个数中的一个即视为符合条件。
所以只需对 1 ~ 2019这个范围内的数字遍历一遍,并且一边找一边加平方和即可。
所以这个题的核心在于检测是否符合条件的算法:
对于每一个数字,利用
对10取余
和÷10
,不断从最低位向高位检测
代码与结果:
#include<iostream>
using namespace std;
bool judge(int VAL);
int main(void){
long long result = 0;
for(int count = 1;count <= 2019;count++){
if(judge(count)){
result += count * count;
}
}
cout << "The result is : " << result << endl;
}
//应用了针对整数的逐位检查算法 (利用整数变小数为零的特征)
bool judge(int VAL){
int n = 0;
while(VAL != 0){
n = VAL % 10; //检查最低位
if( n == 2 || n == 0 || n == 1 || n == 9){
return(true);
}
VAL /= 10;
}
return(false); //所有位都不符合条件,显然数整体不符号条件
}
-
正确结果为
2658417853
-
算法的时间复杂度为
O(n)
2.数列求值
问题描述:
给定数列 1, 1, 1, 3, 5, 9, 17, …,从第 4 项开始,每项都是前 3 项的和。
求第 20190324 项的最后 4 位数字。
分析:
本题根据规律来计算很简单,但是需要注意大数问题,即如果一直按照原数计算的话可能会溢出。而题目最后是要求给出最后四位数,所以在计算中可以进行取余,使得数字一直保持在很小的范围内。
其次就是有关空间的占用,如何使用较少的空间来完成结果存储。
结果和代码:
1.有关溢出:
- 范围
No Value
26 : 1800281
27 : 3311233
28 : 6090307
29 : 11201821
30 : 20603361
31 : 37895489
32 : 69700671
33 : 128199521
34 : 235795681
35 : 433695873
36 : 797691075
37 : 1467182629
38 : -1596397719
39 : 668475985
40 : 539260895
41 : -388660839
long类型的范围是:-2147483648~2147483647
可以看到,从第38项就开始溢出了。
- 增长趋势
可以看到这个数列的增长趋势,显然不能用简单的相加方式来做这个题。
2.代码:
使用 四个int变量来迭代即可。既不需要大数类型,也不需要数组。
#include<iostream>
using namespace std;
int main(void){
int d1, d2, d3;
int temp;
d1 = d2 = d3 = 1; //初始化数列的前三位
for(int count = 4;count <= 20190324;count++){
temp = ( d1 + d2 + d3 ) % 10000;
d1 = d2;
d2 = d3;
d3 = temp;
}
cout<<temp<<endl;
return(0);
}
- 正确结果为
4659
- 程序复杂度为
O(n)
3.附录:各种整数类型的范围
类型 | 范围 | 长度/字节数 |
---|---|---|
short | -32768 ~32767 | 2 |
unsigned short | 0 ~65535 | 2 |
unsigned int | 0~4294967295 | 4 |
int | -2147483648~2147483647 | 4 |
unsigned long | 0~4294967295 | 4 |
long | -2147483648~2147483647 | 4 |
long long | -9223372036854775808~9223372036854775807 | 8 |
unsigned long long | 0~18446744073709551615 | 8 |
3.最大降雨量
问题描述:
由于沙之国长年干旱,法师小明准备施展自己的一个神秘法术来求雨。这个法术需要用到他手中的 49 张法术符,上面分别写着 1 至 49 这 49 个数字。法术一共持续 7 周,每天小明都要使用一张法术符,法术符不能重复使用。每周,小明施展法术产生的能量为 这周 7 张法术符上数字的中位数。法术施展完 7 周后,求雨将获得成功,降雨量为 7 周能量的中位数。
由于干旱太久,小明希望这次求雨的降雨量尽可能大,请大最大值是多少?
分析:
题目可以简化为:
四十九个数字,从 1 ~ 49, 排列成7组数**(称为数组 1 ~ 7)**,每组7个数,不重复
7组数各自的中位数按序排列成一个长度为7的数组**(称为数组8)**,问如何排列使得数组8的中位数最大
这个题目不需要编程去计算,显然容易想到用全排列去暴力计算,但是这样会复杂很多。
使用简单的画图分析即可得到结果:
令 x1 ~ x7 为数组1~7的`中位数`,那么将数组1~7排序之后的样子:
x x x x1 x x x
x x x x2 x x x
x x x x3 x x x
x x x x4 x x x
x x x x5 x x x
x x x x6 x x x
x x x x7 x x x
将7个数组按照他们的中位数大小进行排序,显然仍然能够得到上图一样的布局
不过此时有:
- x1 < x2 < x3 ..... < x7
- 在一行中右边的比左边的大
- 上面的一列比下面的一列大
- x4即为最后的降雨量
红色标出的即为大于 x4 的值(15个),可以推算出 x4 最大只能是 49 - 15 = 34
x x x x1 x x x
x x x x2 x x x
x x x x3 x x x
x x x x4 `x x x`
x x x `x5 x x x `
x x x `x6 x x x `
x x x `x7 x x x `
结果:
- 34