笔试记录集---1

本文探讨了如何用动态规划法求解使给定数成为Fibonacci数的最少步数,以及利用二维数组快速查找单词的方法,还涉及到了杨辉三角的构造。
摘要由CSDN通过智能技术生成

 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数"
示例1
输入:15
输出:2

 

解题思路:题目说最少多少步可以让目标值变成一个fibonacci数列,这个时候就要明确一个问题了,那就是把这个数变成fib数一定是通过一直加1或者一直减1来完成的,因为如果是加一部分,在减一部分那么就相当于在做来回的循环过程,这个是没有意义的。当明确了一定是通过一直加1或者一直减1的方法让他变成fib数列之后,那么只需要知道给出的这个值在哪两个数之间即可。所以可以定义一个数组,然后把1-1000000之间的fib数全部记录在数组中,然后用两端的值减掉输入的值,取最小就可以得出最终结果。由于这个地方只需要知道前两个值然后就可以知道第三个值,那么可以使用滚动不记录的方式,来得出输入的值在哪两个数之间。

下面是具体代码:

#include <iostream>
using namespace std;
int n;
int main()
{
cin >> n;
int a = 0, b = 1, c = 1;
//当最右侧的值大于输入的值的时候,就需要接着往下找
while(n > c)
{
        //滚动数组的形式
        a = b;
        b = c;
        c = a + b;
}
cout << min(c - n, n - b) << endl;
return 0;
}

单词搜索

描述
给出一个二维字符数组和一个单词,判断单词是否在数组中出现,
单词由相邻单元格的字母连接而成,相邻单元指的是上下左右相邻。同一单元格的字母不能多次使用。

数据范围:
0 < 行长度 <= 100
0 < 列长度 <= 100
0 < 单词长度 <= 1000

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

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

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

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

解题思路:分析题目上下左右可以用两个数组来实现 int dx[4]={0,0,1,-1};int dy[4]={1,-1,0,0};又因为同一单元格的字母不能够多次使用,所以要用一个数组来记录已经遍历过的值,当遍历了之后如果发现这个位置不是想要的结果值,那么就要把这个位置重新设置为没有被遍历过,这样可以方便以后其他位置来进行遍历。

下面是具体实现的代码

class Solution
{
 int m, n;
 bool vis[101][101] = { 0 };
 int dx[4] = {0, 0, 1, -1};
 int dy[4] = {1, -1, 0, 0};
public:
 bool exist(vector<string>& board, string word) 
 {
     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])
             {
                 //这个地方为什么要判断呢?是因为判断当前这个位置的值是否可以遍历完word这个单词
                  //如果可以,就返回true.这个位置不可以,就接着看board里面的其他位置
                 if(dfs(board, i, j, word, 0)) return true;
             }
         }
     }
    //当所有的位置都不能找到的时候,就返回false;
     return false;
 }

 bool dfs(vector<string>& board, int i, int j, string& word, int pos)
 {
     if(pos == word.size() - 1)
     {
         //递归出口,已经遍历到最后一个相等的单词了,那么就可以找到
         return true;
     }
     //记录已经遍历过的值
     vis[i][j] = true;
     for(int k = 0; k < 4; k++)
     {
         int a = i + dx[k], b = j + dy[k];
           if(a >= 0 && a < m && b >= 0 && b < n && !vis[a][b] && board[a][b] == word[pos+1])
         {
             if(dfs(board, a, b, word, pos + 1)) return true;
         }
     }
    //如果把i,j位置的上下左右都遍历完了之后,还没有返回true,那就表明这个位置进行dfs找不到word
    //那这次遍历就是无效的,所以把当前遍历过的值改为没有被遍历,方便后续其他位置根据上下左右来
    //访问这个值
     vis[i][j] = false;
     return false;
     }
};

杨辉三角

描述

KiKi知道什么叫杨辉三角之后对杨辉三角产生了浓厚的兴趣,他想知道杨辉三角的前n行,请编程帮他解答。杨辉三角,本质上是二项式(a+b)的n次方展开后各项的系数排成的三角形。其性质包括:每行的端点数为1, 一个数也为1;每个数等于它左上方和上方的两数之和。

输入描述:

第一行包含一个整数数n。 (1≤n≤30)

输出描述:

包含n行,为杨辉三角的前n行,每个数输出域宽为5。

示例1

输入:6

输出:

    1
    1    1
    1    2    1
    1    3    3    1
    1    4    6    4    1
    1    5   10   10    5    1

解题思路:通过观察可知,除了每行的第一个和最后一个是1之外,那么其他位置的值都是

通过公式v[i][j]=v[i-1][j]+v[i-1][j-1]而来,那么我们只需要设置一个二维数组,在进行二维数组填写的时候,只需要填写下三角就可以了。然后打印也是同样如此,打印出下三角就能够满足结果。

下面是具体代码:

#include <iostream>
using namespace std;

//用一个数组来记录,这里用的是下标为0的位置来隐射成下标为1的位置
//全局的数组直接自动全部填写的是0
int dp[31][31];
int main()
{
 int n;
 cin >> n;
 dp[1][1] = 1;
 for(int i = 2; i <= n; i++)
 {
    //j<=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++)
     {
       //题目要求每个值之间是5个域的间隔,所以用%sd
       printf("%5d", dp[i][j]);
     }
     printf("\n");
 }
 return 0;
}

  • 17
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值