笔试强训day4

Fibonacci数列

题目地址:Fibonacci数列

描述

Fibonacci数列是这样定义的:

F[0] = 0

F[1] = 1

for each i ≥ 2: F[i] = F[i-1] + F[i-2]

因此,Fibonacci数列就形如:0, 1, 1, 2, 3, 5, 8, 13, ...,在Fibonacci数列中的数我们称为Fibonacci数。给你一个N,你想让其变为一个Fibonacci数,每一步你可以把当前数字X变为X-1或者X+1,现在给你一个数N求最少需要多少步可以变为Fibonacci数。

输入描述

输入为一个正整数N(1 ≤ N ≤ 1,000,000)

输出描述

输出一个最小的步数变为Fibonacci数"

题目解析

题目为基础的fibonacci数列的应用,其后续数组皆可推导出来,推导公式为:F[i] = F[i-1] + F[i-2]。

我们也可以直接定义常数来模拟其推导过程。

代码及解释展示

复制代码
#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    //a代表f[0],b代表f[1],c代表f[0]+f[1]
    int a=0,b=1,c=1;
    //后续a代表f[i-2],b代表f[i-1],c代表f[i-2]+f[i-1]
    while(n > c)
    {
        a = b;//a向后挪一位
        b = c;//b向后挪一位
        c = a + b;//f[i-1] + f[i-2]
    }
    //当脱离while时,c已经大于n,并且满足条件f[i-1] <= n <= f[i] 
    //接下来我们要找n距离f[i-1]与f[i]之间的最小距离
    cout << min(c - n,n - b) << endl;
    return 0;
}
// 64 位输出请用 printf("%lld")

单词搜索

题目地址:单词搜索

描述

给出一个二维字符数组和一个单词,判断单词是否在数组中出现,

单词由相邻单元格的字母连接而成,相邻单元指的是上下左右相邻。同一单元格的字母不能多次使用。

数据范围:

0 < 行长度 <= 100

0 < 列长度 <= 100

0 < 单词长度 <= 1000

例如:

给出的数组为["XYZE","SFZS","XDEE"]时,对应的二维字符数组为:

若单词为"XYZZED"时,应该返回 true,也即:

若单词为"SEE"时,应该返回 true,也即:

若单词为"XYZY"时,应该返回 false。

解题思路

本题为搜索问题,通过对周围的搜索进行条件验证,可用深度优先搜索(DFS),或广度优先搜索(BFS)进行搜索。

代码及解释展示

dfs代码

复制代码
#include <vector>
class Solution {
public:
    int m,n;
    bool exist(vector<string>& board, string word) {
        // write code here   
        m = board.size(),n=board[0].size();
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(board[i][j] == word[0])
                {
                    if(dfs(board,i,j,word,1))return true;
                }
            }
        }
        return false;
    }
    //走过的路就标记为true,防止反复走同一个位置
    bool vis[105][105];
    //dx和dy用于控制方向
    int dx[5] = { 0, 0,-1, 1};
    int dy[5] = { 1,-1, 0, 0};
    //设置dfs函数
    //i和j代表位置,word表示当前的字符,pos代表有多少个符合答案字符串的字符数量
    bool dfs(vector<string>& board,int i,int j, string& word,int pos)
    {
        //dfs出口,当pos满足字数,即返回true
        if(pos == word.size())return true;
        //当前位置设置为true,防止后续再次重复走当前位置
        vis[i][j] = true;
        for(int k=0;k<4;k++)
        {
            //让i,j分别加上dx,dy对应的值即可控制下一个位置的上下左右
            int a = i + dx[k],b = j + dy[k];
            //开始进行判断
            //a,b的判断是防止越出边界
            //vis[a][b]是为了判断该位置是否走过
            //board的判断是为了判断a,b位置的字母是否符合条件
            if(a >= 0 && a < m && b >= 0 && b < n && !vis[a][b] && board[a][b] == word[pos])
            {
                //dfs开始递推
                if(dfs(board,a,b,word,pos+1))return true;
            } 
        }
        //复原当前位置,在未出答案前,防止影响下一位置代码运行
        vis[i][j] = false;
        return false;
    }
};

bfs代码

复制代码
#include <vector>
#include <queue>
#include <tuple>
using namespace std;

class Solution {
public:
    int m, n;
    bool exist(vector<string>& board, string word) {
        if (word.empty()) return true;
        m = board.size();
        if (m == 0) return false;
        n = board[0].size();
        
        //用于控制上下左右
        int dx[4] = {0, 0, -1, 1};
        int dy[4] = {1, -1, 0, 0};
        
        // BFS队列,存储内容为:行, 列, 当前匹配位置, 访问状态
        queue<tuple<int, int, int, vector<vector<bool>>>> q;
        
        // 初始化队列,找到所有单词首字母的位置
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (board[i][j] == word[0]) {
                    vector<vector<bool>> visited(m, vector<bool>(n, false));
                    visited[i][j] = true;
                    q.push({i, j, 1, visited});
                    
                    // 如果单词只有一个字符
                    if (word.size() == 1) {
                        return true;
                    }
                }
            }
        }
        
        // BFS主循环
        while (!q.empty()) {
            auto [i, j, pos, visited] = q.front();
            q.pop();
            
            // 探索四个方向
            for (int k = 0; k < 4; k++) {
                int a = i + dx[k];
                int b = j + dy[k];
                
                // 检查边界、访问状态和字符匹配
                if (a >= 0 && a < m && b >= 0 && b < n && !visited[a][b] && board[a][b] == word[pos]) {
                    // 如果已经匹配完所有字符
                    if (pos + 1 == word.size()) {
                        return true;
                    }
                    
                    // 创建新的访问状态
                    vector<vector<bool>> new_visited = visited;
                    new_visited[a][b] = true;
                    
                    // 加入队列
                    q.push({a, b, pos + 1, new_visited});
                }
            }
        }
        
        return false;
    }
};

杨辉三角

题目地址:杨辉三角

描述

杨辉三角形,又称帕斯卡三角形,第 i+1 行是二项式展开 的系数。

三角形中任意元素等于上一行同列元素与上一行前一列元素之和。

下面给出杨辉三角形的前 4 行:

1

1 1

1 2 1

1 3 3 1

给定正整数n,请输出杨辉三角形的前n行。

输入描述

在一行输入一个整数 n(1≦n≦34)。

输出描述

输出杨辉三角形的前 n 行。每一行从该行第一个元素开始,依次输出;每两个数之间用一个空格分隔。请不要在行末输出多余的空格。

题目解析

如果我们把第二行第二列我们可以看作dp[1][1],剩余的对应其该对应的位置,可以看到,未存在实数的值全用0代替:

0 0 0 0 0 0

0 1 0 0 0 0

0 1 1 0 0 0

0 1 2 1 0 0

0 1 3 3 1 0

仔细观察我们可以使用公式:dp[ i ][ j ] = dp[ i-1 ][ j ] + dp[ i-1][ j-1],即使是杨辉三角的边界也变成1+0=1。

代码及解释展示

复制代码
#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    //用long long是为了防止过大报错
    long long dp[40][40] = {0};

    //直接赋值给dp[1][1] = 1即可
    //后续使用dp[i][j] = dp[i-1][j] + dp[i-1][j-1]都可推导出
    dp[1][1] = 1;
    for(int i=2;i<=n;i++)
    {
        for(int j=1;j<=i;j++)
        {
            dp[i][j] = dp[i-1][j] + dp[i-1][j-1];
        }
    }
    //打印答案
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=i;j++)
        {
            cout<<dp[i][j];
            if(j!=i)
                cout<<" ";
        }
        cout<<endl;
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

今天的学习到此结束\\\\٩( 'ω' )و ////

相关推荐
自然语2 小时前
人工智能之数字生命-学习的过程
数据结构·人工智能·深度学习·学习·算法
Yuezero_2 小时前
Research Intern面试(一)——手敲LLM快速复习
pytorch·深度学习·算法
wyiyiyi2 小时前
【数据结构+算法】非递归遍历二叉树的理解
大数据·数据结构·笔记·算法·leetcode·数据分析
2401_893326622 小时前
力扣1971.寻找图中是否存在路径
算法·leetcode·职场和发展
zs宝来了2 小时前
HOT100-技巧类型题
数据结构·算法
Ayanami_Reii2 小时前
进阶数据结构-FenwickTree
数据结构·算法·树状数组·fenwick tree
爪哇部落算法小助手3 小时前
每日两题day59
数据结构·c++·算法
Brduino脑机接口技术答疑3 小时前
脑机接口数据处理连载(二) 数据源头解析:脑电信号的采集原理与数据特性
人工智能·python·算法·数据分析·脑机接口
吃着火锅x唱着歌3 小时前
LeetCode 1010.总持续时间可被60整除的歌曲
算法·leetcode·职场和发展