ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

基础算法题

2022-06-29 14:00:58  阅读:111  来源: 互联网

标签:10 int sum 基础 long 算法 ans include


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<iostream>
  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<iostream>
  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<iostream>
  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<iostream>
  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<iostream>
  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<str[i];i++){
  9          if(i<13){
 10             //now windowns
 11             now*=str[i]-'0';
 12          } else if(str[i]!='0')
 13          {
 14             now*=str[i]-'0';
 15          }else{
 16             count_cnt++;
 17          }
 18
 19          if(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 <<endl;
 33     return 0;
 34 }

11:方向数组

<重定向符

  1 #include<iostream>
  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 <<endl;
 32     return 0;
 33 }

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 <iostream>
#include <cstring>
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] <<endl;
        if(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] <<endl;

14最长考拉兹序列

考了在定义在正证书及上迭代的规则

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万的数中 开始迭代的生成的序列最长 递归 递归

#include<iostream>
using namespace std;

long long  num[10000005];
 long long func(long long x){
        if(x==1){
            return 1;
        }
        if(x<10000000&&num[x]!=0){
              return num[x]; 
        }
        long long t;
        if(x%2 == 0){
          t= func(x/2)+1;
        }else{
            t=func(3* x +1)+1;
        }
        if(x<10000000){
            num[x]=t;
        }
        return t;
   }


int main(){
   long long ans=0 ,mmax=0;
   for(int i=1;i<=10000000;i++){
   long long  t =func(i);
   if(t>mmax){
     mmax =t;
     ans=i;
   }

  }
  cout<< ans <<endl;
return 0;
}

组和排列 我反正看不懂

#include <iostream>
using   namespace std;

long long ans[25][25];
int main()
{
  long long fin = 1;
  for (int i = 40, j = 1; i > 20; i--, j++)
  {
    fin*=i;
    fin/=j;
  }

  cout << fin << endl;
  return 0;
}

15:网格路径

从一个2×2网格的左上角出发,若只允许向右或向下移动,则恰好有6条抵达右下角的路径。

动态规划的问题:

递推公式为:

你不能让他从0开始必须从第一位开始算,因为外面是一层保护0

由公式→dp[x[[y]=dp[x-1][y]-dp[x][y-1];

#include <iostream>
using   namespace std;

long long ans[25][25];
int main()
{
  for (int i = 1; i <= 21; i++)
  {
    for (int j = 1; j <= 21; j++)
    {
      if (i == 1 && j == 1) {
        ans[i][j] = 1;
        continue;
      }
      ans[i][j] = ans[i - 1][j] + ans[i][j - 1];
    }
  }
  cout << ans[21][21] << endl;

  return 0;
}

—2:组和排序


25:1000位斐波那契数

ps:实际应该为两个数组辗转相加 ,由于是两个数组来回相加

   #include<iostream>
  2 using namespace std;
  3 void func(int *n1, int *n2){
  4     //n2可能比N1短先更新长度
  5    n2[0]=n1[0]; //更新长度 先给数字的长度
  6    for(int i=1;i<=n2[0];i++){
  7        n2[i]+=n1[i];
  8        if(n2[i]>9){
  9            n2[i+1]+=n2[i]/10;
 10            n2[i]%=10;
 11            if(i==n2[0]){
 12                //最高位变化
 13                 n2[0]++;
 14            }
 15        }
 16    }
 17 }
 18 int main(){
 19    int num[2][1111]={{1,1},{1,1}},a=1,b=1;
 20        for(int i=3;1;i++){
 21        //这个一直会计算下去 1 为真
 22        //两个数组相加
 23            func(num[a],num[b]);
 24            if(num[b][0]>=1000){
 25               cout<< i <<endl;
 26        //这是项数
 27               break;
 28            }
 29            //如果没有就交换值接着+
 30             swap(a,b);
 31           }
 32
 33     return 0;
 34 }

26大整数乘法—高精度

1 存(和加法一致)(数字第一位存长度) 2 算 3进位

某两个数相乘为 min x+y-1 | max x+y

核心的公式为 n=x+y-1 ;

取乘积最小的位数 如果高位则在高位判断进位即可

   #include<iostream>
  2 #include<cstring>
  3 using namespace std;
  4
  5 char s1[1005],s2[1005];
  6 int n1[1005],n2[1005],ans[2005];
  7 int main(){
  8     cin>> s1 >> s2;
  9     n1[0]=strlen(s1),n2[0]=strlen(s2);
 10     for(int i=0,j=n1[0];i<n1[0];i++,j--){
 11          n1[j]=s1[i]-'0';
 12     }
 13     for(int i=0,j=n2[0];i<n2[0];i++,j--){
 14          n2[j]=s2[i]-'0';
 15     }
 16     ans[0]=n1[0]+n2[0]-1;
 17     for(int i=1;i<=n1[0];i++){
 18         for(int j=1;j<=n2[0];j++){
 19             ans[i+j-1]+= n1[i] * n2[j];
 20         }
 21     }
 22     for(int i=1;i<=ans[0];i++){
 23         if(ans[i]>9){
 24             ans[i+1]+=ans[i]/10;
 25             ans[i]%=10;
 26             if(ans[0]==i){
 27                ans[0]++;
 28             }
 29         }else if(i==ans[0] && ans[i+1]!=0){
 30             ans[0]++;
 31         }
 32     }
 33     for(int i =ans[0];i>0;i--){
 34         cout << ans[i];   
 35     }                                                                                                                                              35     }
 36     cout<< endl;
 37     return 0;
 38 }

ps :99x99乘出的为4位, 得到一个四位数 , 由于你是四位数

在存储上你必然由一个三位数进位而来,(因为要考虑高位不进位的场景) 所以用x+y - 1

 

 

标签:10,int,sum,基础,long,算法,ans,include
来源: https://www.cnblogs.com/yijieyufu/p/16423113.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有