面试笔试算法-1

本文介绍了欧拉计划中的若干算法题目,包括3或5的倍数、偶裴波那契数、最大回文数乘积等,强调了解题技巧和思路。同时,讲解了大整数加法和乘法的处理方法,以及在处理过程中需要注意的边界和0的处理。此外,还涉及了动态规划和滑动窗口法在解决连续数字最大乘积问题中的应用。
摘要由CSDN通过智能技术生成

面试笔试算法-欧拉计划
面试笔试算法-二分专题
面试笔试算法-Oj刷题
面试笔试算法-LeetCode刷题
面试笔试算法-STL的使用
面试笔试算法之排列组合与搜索走地图问题

欧拉计划

题目1:3或5的倍数

在这里插入图片描述

解题技巧:

在这里插入图片描述

蓝色框表示3的倍数、绿框是5的倍数、黄框是重复项
利用等差数列分别求出3的倍数的和、5的倍数和相加然后减去重复项15的倍数和
即得结果。时间复杂度为O(1)

#include<iostream>
using namespace std;

int main(int argc, char *grav[])
{
   
    /* 第一种简单的方法,直接判断是否是3和5的倍数进行输出
    int ans = 0;
    for (int i = 1; i < 1000; i++) {
        if (i % 3 == 0 || i % 5 == 0) {
            ans += i;
        }
    }
    cout << ans << endl;
    */
    // 利用上述技巧编程
    int t3 = (3 + 999) * 333 / 2;
    int t5 = (5 + 995) * 199 / 2;
    int t15 = (15 + 990) * 66 / 2;
    cout << t3 + t5 - t15 << endl;
    return 0;
}

题目2:偶裴波那锲数

在这里插入图片描述

解题思路

在这里插入图片描述

只需要三个变量来回循环利用计可!不断更新a、b、c的值

代码演示
#include<iostream>
using namespace std;
int main(int argc, char *grav[])
{
   
    int a = 1, b = 1, c = 2, ans = 0;
    while (c <= 4000000) {
   
        if (c % 2 == 0) {
   
            ans += c;
        }
        c = b + c;
        a = b;
        b = c - b;
    }
    cout << ans << endl;
    return 0;
}

题目4:最大回文数乘积

在这里插入图片描述

解题技巧

在这里插入图片描述

首先定义一个临时的变量t用来存储反转后的数字
通过while循环来进行取余求模进行反转
如果t与原始的数据相等则是回文数

#include<iostream>
using namespace std;

int func(int x) {
   
    int t = 0, row = x;
    while (x) {
   
        t = t * 10 + x % 10;
        x /= 10;
    }
    return t == row;
}

int main(int argc, char *grav[])
{
   
    int ans = 0;
    for (int i = 100; i < 1000; i++) {
   
        for (int j = i; j < 1000; j++) {
   
            int t = i * j;
            if (func(t)) {
   
                ans = max(ans, t);
            }
        }
    }
    cout << ans << endl;
    return 0;
}

题目6:平方的和与和的平方之差

在这里插入图片描述

比较基础,直接计算

#include<iostream>
using namespace std;
int main(int argc, char *grav[])
{
   
    int sum = 0, psum = 0;
    for (int i = 1; i <= 100; i++) {
   
        sum += i;
        psum += i * i;
    }
    cout << sum * sum - psum << endl;
    return 0;
}

题目8:连续数字最大乘积(滑动窗口法)

在这里插入图片描述

思路
  • 首先将数据复制,保存在本地为字符串
    检查复制后的格式:删掉空格、换行
    读入时用数组存储,读取每位时需转换为数字(- ‘0’)
  • 滑动窗口法
    静态窗口:固定窗口大小
    动态窗口:一般称为双指针
  • 解法:
    使用滑动窗口法——静态窗口
    只需考虑窗口进的数和出的数,可以减少运算次数
    出:除以
    进:乘以
    注意值是否为0
    在这里插入图片描述数据中的关键是对0的处理,首先定义一个0的计数器zero_cnt,进入滑动窗口时:为0时,zero_cnt++,不更新结果,不是0,则乘以原有数的成绩,相反,出滑动窗口时,为0时,zero_cnt–,不是0,原有结果除以要出去的数,当zero_cnt 等于0时,更新答案。
#include<iostream>
using namespace std;
char num[1005];
long long  ans, zero_cnt, now = 1;
int main(int argc, char *grav[])
{
   
    cin >> num;
    for (int i = 0; i < 1000; i++) {
   
        if (i < 13) {
   
            now *= num[i] - '0';
        } else {
   
            if (num[i] == '0') {
   
                zero_cnt++;
            } else {
   
                now *= num[i] - '0';
            }
            if (num[i - 13] == '0') {
   
                zero_cnt--;
            } else {
   
                now /= num[i - 13] - '0';
            }
        }
        if (!zero_cnt) {
   
            ans = max(ans, now);
        }
    }
    cout << ans << endl;
    return 0;
}
  • 前13位不含0,可以直接计算now
  • 注意窗口内0的情况
    ❗定义一个0的计数器
  • ❌是否可以碰见0就将乘积变为1?
    不行,需要存除除0以外数的乘积
  • ❌是否可以将0直接变为1?可以减少判断次数,只需要对进来的值判断0
    但这样是不可以的,因为有可能不满13位的两个0之间的数很大
    比如11022340111111111111111111
    执行时报错:floating point exception
    除以0了可能会导致该错误
    错误地估计了上界,9^13肯定超过了int类型的上界,所以使用long long
    在这里插入图片描述
题目11:方阵中的最大乘积(方向数组)

在这里插入图片描述

思路

在这里插入图片描述

如上图所示:通过一个简单的矩阵推算出方向数组的八个方向,上(-1, 0)、下(1,0)、左(0,-1)、右(0,1)、右上(-1,1)、右下(1,1)、左下(1,-1)、左上(-1,-1)。

  • 计算某个数各个方向的连续4个数的乘积最大值
    计算问题:为了避免重复,只需要计算连续的4个方向进行计算。
    边界问题:1、判断边界;2、边界补0(至少三圈0)
#include<iostream>
using namespace std;

int dirx[4] = {
   0, 1, 1, 1};
int diry[4] = {
   1, 1, 0, -1};
int num[30][30], ans;

int main(int argc, char *grav[])
{
   
    for (int i = 5; i < 25; i++) {
   
        for (int j = 5; j < 25; j++) {
   
            cin >> num[i][j];
        }
    }
    for (int i = 5; i < 25; i++) {
   
        for (int j = 5; j < 25; j++) {
   
            // 遍历四个方向
            for (int k = 0; k < 4; k++) {
   
                int t = num[i][j];
                // 四个方向的延伸的四个数
                for (int l = 1; l < 4; l++) {
   
                    int x = i + dirx[k] * l;
                    int y = j + diry[k] * l;
                    t *= num[x][y];
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值