基础算法题
Problem
3或5的倍数
2:偶斐波那契数
4:最大回文乘积
5 窗口移动
11:方向数组
13大整数加法 、
14最长考拉兹序列
15:网格路径
25:1000位斐波那契数
1:3或5的倍数
在小于10的自然数中,3或5的倍数有3、5、6和9,这些数之和是23。
求小于1000的自然数中所有3或5的倍数之和。
考查倍数()% 取模运算符,整除后的余数 ,整除则为倍数
1 #include
2 using namespace std;
6 int main(){
7 int ans=0; 8 for(int i =1;i<1000;i++){
9 if(i%3==0||i%5==0){
10 ans+=i;
11 }
12 }
13 cout << ans << endl;
14 return 0;
15 }
等差数列 优化重复标记
#include
2 using namespace std;
3 首项加末项 * (sum / 首选) /2
4 int main (){
5 int sum3 =(3+999)*333/2;
6 int sum5 =(5+995)*199/2;
7 int sum15=(15+990)*66/2;
8
9 int reult = sum3 + sum5 -sum15;
10 cout << reult << endl;
11
12 return 0; 13 }
2:偶斐波那契数
斐波那契数列中的每一项都是前两项的和。由1和2开始生成的斐波那契数列的前10项为:
1,2,3,5,8,13,21,34,55,89,…
考虑该斐波那契数列中不超过四百万的项,求其中为偶数的项之和。
1 #include
2 using namespace std;
3
4 int main(){
5 long long temp=0;
6 int a=1;
7 int b=2;
8 while(b<4000000){
9 if(b %2==0 ) {
10 temp +=b;
11 }
12 b=a+b;
13 a=b-a; 14 }
15 cout << temp << endl;
16 return 0;
17 }
4:最大回文乘积
回文数就是从前往后读和从后往前读都一样的数。由两个2位数相乘得到的最大的回文数是 9009=91×99。
求由两个3位数相乘得到的最大的回文数。
最重要的反转数字 取模可以理解为lsat的数字
主方法这 公式 临时数据 =t * 10 + {x} %* 10
x/=10; 是为了last 的位子往前移
1 #include
2 using namespace std;
3
4
5 int func(int x){
6 int raw =x ,t=0;
7 while(x){
8 t= t * 10+ x % 10;
9 x=x/10;
10 }
11 int reulte =raw==t;
12 return reulte;
13 }
14
15
16
17 int main(){
18 int temp=0;
19 for(int i=100; i<1000;i++){ 20 for(int j=i;j<1000;j++){
21 if(func(i*j))
22 {
23 temp=max(temp,i*j);
24 }
25 }
26 }
27 cout << temp << endl;
28 return 0;
29 }
30
5 窗口移动

1 #include
2 using namespace std;
3
4 char str[1005];
5 int main(){
6 long long ans =0, now =1 ,count_cnt=0;
7 cin >> str;
8 for(int i=0;i=13){
20 //则窗体向后走
21 if(str[i-13]!='0'){
22 now /=str[i-13]-'0';
23 }
24 else{
25 count_cnt--;
26 }
27 }
28 if(count_cnt ==0){ 29 ans=max(ans,now);
30 }
31 }
32 cout << ans <
11:方向数组

<重定向符
1 #include
2 using namespace std;
3
4
5 int num[30][30] ,ans;
6 int dirx[4]={-1,0,1,1};/*定义方向数组*/
7 int diry[4]={1,1,1,0};
8
9 int main(){
10 for(int i=5;i<25;i++){
11 for(int j=5;j<25;j++){ 12 cin >> num[i][j];
13 }
14 }
15
16 for(int i=1;i<25;i++){ //x 行
17 for(int j=1;j<25;j++){ // y 列
18 for(int k=0;k<4;k++){ //方向
19 int t=num[i][j];
20 for(int l=1;l<4;l++){ //除了自己的走三步数
21 //新坐标
22 int x= i+l * dirx[k];
23 int y= j+l * diry[k]; //l倍的纵坐标
24 t *=num[x][y];//这个格子的值x到方向的答案中
25 }
26 ans=max(ans,t); //尝试更新答案 求玩一次答案则更新一次答案
27 }
28 }
29 }
30
31 cout<< ans <
13大整数加法
step1: 长度大于int 64的数字加法一般有另外的处理方法
通过两个字符数组存 转为数值数据 进行计算
先把输入的数字长度 存在下标为0 的位子 .
step2:通过num数组来存字符数组的值(经数组反过来存)
step3:通过取出最大的数组位数
作为sum数组长度, 则将sum数组num1[i]+num2[i];
step4: 已经 拿到了加数值了 //则进位
如果下表位数大于9则是需要进位的
公式为:sum[i+1]=sum[i+1]+sum[i]/10;
sum[i]%=10;
刚刚定义的下标长度0 用于判断最高位是否有进位如果则最高位长度也随之发生变化
最后倒叙输出sum数组即可
#include
#include
using namespace std;
char s1[1005],s2[1005];
int num1[1005],num2[1005],sum[1005];
int main(){
cin>> s1>> s2;
num1[0]=strlen(s1);
num2[0]=strlen(s2);
//数字数组的下表 j;
for(int i=0,j=num1[0];s1[i];i++,j--){
num1[j]=s1[i]-'0'; //必须减去0才能获得字符的值
}
for(int i=0,j=num2[0];s2[i];i++,j--){
num2[j]=s2[i]-'0';
}
sum[0]=max(num1[0],num2[0]);
for(int i=1;i<=sum[0];i++){
sum[i]=num1[i]+num2[i];
}
//进位
for(int i=1;i<=sum[0];i++){
cout<< sum[i] <9){
sum[i+1]+=sum[i]/10;
sum[i]%=10;
if(i==sum[0]){
sum[0]++;
}
}
}
//倒着输出
for(int i=sum[0];i>0;i--){
cout<< sum[i];
}
cout << endl;
return 0;
}
cout<< sum[i] < 考了在定义在正证书及上迭代的规则 n → n/2 (n is even) 如果为偶数 n → 3n + 1 (n is odd) 若n为奇数 从13开始,可以迭代生成的序列 13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1 在小于100万的数中 开始迭代的生成的序列最长 递归 递归 组和排列 我反正看不懂 从一个2×2网格的左上角出发,若只允许向右或向下移动,则恰好有6条抵达右下角的路径。 动态规划的问题: 递推公式为: 由公式→dp[x[[y]=dp[x-1][y]-dp[x][y-1]; —2:组和排序 ps:实际应该为两个数组辗转相加 ,由于是两个数组来回相加 1 存(和加法一致)(数字第一位存长度) 2 算 3进位 某两个数相乘为 min x+y-1 | max x+y 核心的公式为 n=x+y-1 ; 取乘积最小的位数 如果高位则在高位判断进位即可 ps :99x99乘出的为4位, 得到一个四位数 , 由于你是四位数 在存储上你必然由一个三位数进位而来,(因为要考虑高位不进位的场景) 所以用x+y - 114最长考拉兹序列
#include#include
15:网格路径
你不能让他从0开始必须从第一位开始算,因为外面是一层保护0#include
25:1000位斐波那契数
#include26大整数乘法—高精度
#include