首页 > 编程语言 >算法题目(2)

算法题目(2)

时间:2022-10-03 09:22:38浏览次数:69  
标签:arr 题目 cur int step next 算法 num

题目1

定义何为步骤和?
比如680,680 + 68 + 6 = 754,680的步骤和叫754
给定一个正数num,判断它是不是某个数的步骤和

思路

单调性。思路过程:首先想到如果直接从步骤和num倒推原来的数很麻烦,进而想到从1计算步骤和到num,找匹配的,但是这种枚举太多了,然后想到能不能二分,进而想到看看能不能找到单调性。有这么一个结论:x的步骤和是A,y的步骤和是B,如果x > y,则A > B。因为步骤和的定义是首先加上这个数本身,然后依次累加这个数除以10后向下取整的结果,x > y,x/10 >= y /10,x/100 >= y /100......所以如果x > y,则A > B。这样我们就可以二分了。首先num二分之后看看二分的数的步骤和是否是num,如果小于num则往右二分,大于num则往左二分,直到没有数字了,就返回-1。根据步骤和的定义我们可以知道步骤和num一定大于原来的数字,所以0~num的范围实际是包含了原来的数字的,所以不必担心二分的范围内不包含原来的数字。

代码

int main()
{
	int num;
	cin >> num;
	int L = 0;
	int R = num;
	int mid;
	int flag = false;
	while (L <= R)
	{
		mid = L + (R - L) / 2;
		int stepNum = getStepNum(mid);
		if (stepNum < num)
		{
			L = mid + 1;
		}
		else if (stepNum > num)
		{
			R = mid - 1;
		}
		else
		{
			flag = true;
			cout << mid << endl;
		}
	}
	if (!flag)
	{
		cout << -1 << endl;
	}

	return 0;
}

涉及知识

找单调性,或者人为构建单调性,然后二分

题目2

给定一个数组arr,每个位置上的值代表机器人在当前位置时,可以选择直接跳到下标为 当前位置+当前位置的值以内 的位置。机器人从0位置开始,请问走到最后一个位置最少需要跳几步

思路

准备三个变量,变量step为当前跳了多少步,变量cur为当前跳step步最远可以到达的位置,变量next为如果跳step+1步最远可以到达的位置。机器人起始位置为arr[0],step起始值为0,跳0步最远也只能为0,所以cur的起始值为0,跳0+1步可以到达的最远位置就是arr[0]+0,所以next起始值为arr[0]。准备一个指针变量i,开始遍历数组,同时更新step、cur、next,更新的策略是:当我来到i位置时,先看跳step步的最远位置能不能覆盖到i,即cur是否大于等于i,如果是,那么看看i+arr[i]是否大于next的值决定next是否更新,如果cur < i,那么step+1,因为next就是step+1时能跳到的最远的位置,所以cur=next,而next继续看i+arr[i]是否大于当前next的值决定next是否更新。直到i越界,返回step

代码

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;

int main()
{
	int n;
	cin >> n;
	vector<int> arr(n);
	int step = 0;
	int cur = 0;
	int next = 0;
	for (int i = 0; i < n; i++)
	{
		cin >> arr[i];
		if (cur < i)
		{
			step++;
			cur = next;
		}
		next = max(next, arr[i] + i);
	}
	cout << step << endl;
	return 0;
}

题目3

谷歌面试题扩展版
面值为1~N的牌组成一组,
每次你从组里等概率的抽出1~N中的一张
下次抽会换一个新的组,有无限组
当累加和 < a时,你将一直抽牌
当累加和 >= a且 < b时,你将获胜
当累加和 >= b时,你将失败
返回获胜的概率,给定的参数为N,a,b

思路

递归。当我现在的值为i的时候,我的胜率是:

  1. 如果我的值 >= a且 < b,那么胜率是1.0;如果我的值 >= b,那么胜率是0.0
  2. 如果我的值小于a,那么我的胜率是的((i+2的胜率) + (i+2的胜率)+ (i+3的胜率) + ... + (i+N的胜率)) / N,因为每次抽到的数字概率都是1 / N。

代码

double f(int cur, int N, int a, int b)
{
	if (cur >= a && cur < b)
	{
		return 1.0;
	}
	if (cur >= b)
	{
		return 0.0;
	}
	double w = 0.0;
	for (int i = 1; i <= N; i++)
	{
		w += f(cur + i, N, a, b);
	}
	return w / 10;
}

int main() 
{
	int N, a, b;
	cin >> N;
	cin >> a;
	cin >> b;
	cout << f(0, N, a, b) << endl;
	return 0;
}

优化扩展

for (int i = 1; i <= N; i++)
{
    w += f(cur + i, N, a, b);
}

在递归函数中有这样一个枚举行为,其实它是可以被省去的。具体看视频https://www.bilibili.com/video/BV1g3411i7of?p=150&vd_source=77d06bb648c4cce91c6939baa0595bcd P150 20:33

题目4

约瑟夫环问题

思路

证明思路很负责,是通过Y = X % i这个函数变换来的。假设当前链表长度为i,数到m杀人,前一轮编号 = (后一轮编号 + m - 1) % i + 1
最后活下来的人在最后一轮的编号一定是1,链表长度为1,所以从后往前推,每次求出最后活下来的人在前一轮的编号,最后求出第一轮的时候这个人的编号即可

代码

//递归
int lastRamaining1(int n, int m)
{
    return getLive(n, m) - 1;    //-1是因为leetcode的题目要求不同
}
int getLive(int n, int m)    //n:剩n个人。m:数到m杀人
{
    if(n == 1)
    {
        return 1;
    }
    return (getLive(n - 1, m) + m - 1) % n + 1;
}

//迭代
int lastRamaining1(int n, int m)
{
    int ans = 1;
    int r = 1;
    while(r <= n)
    {
        ans = (ans + m - 1) % r + 1;
        r++;
    }
    return ans - 1;     //-1是因为leetcode的题目要求不同
}

涉及知识

涉及到剃刀函数的就想函数在坐标系中的移动变换(左加右减,上加下减)

题目5

思路

代码

题目6

思路

代码

标签:arr,题目,cur,int,step,next,算法,num
From: https://www.cnblogs.com/hbwang1115/p/16748532.html

相关文章

  • 饿了么推荐算法演进
    导读:本次分享的主要内容包括以下三个方面:首先是介绍推荐业务背景,包括推荐产品形态及算法优化目标;然后是算法的演进路线;最后重点介绍在线学习是如何在饿了么推荐领域实践的......
  • 前端-面试实战题目积累
    vue单向数据流的原理所有的prop使得其父子之间形成一个单向下行绑定,父组件--->子组件;父组件prop的更新会下流到子组件中,反过来不行;防止子组件意外变更父组件的状态,导致......
  • 19 -- 排序算法之归并排序
          从合并的示意图中可以看到,其实现思路与“合并两个有序的单链表,使之合并完后依然有序”类似。 1importjava.util.Arrays;23publicclassMe......
  • knn 算法以及电影种类预测&莺尾花种类预测
    1.简介 K-NearestNeighbor算法又叫KNN算法(最近邻算法,k是选取几个距离其最近的样本作为参考),这个算法是机器学习里面一个比较经典的分类和回归算法。 定义:如果一个样本在......
  • 题目集1~3的总结性Blog
    一、前言对于本次blog所涉及的题目,个人感觉主要是对于String类型的变量处理,以及对于面向过程所使用的类的用法有较高要求,难度也是逐渐递增,尤其是点线三角形更是如此,......
  • 题目集1~3的总结性Blog
    1.前言第一次作业难度相对较低,主要注重字符串的处理。第二次作业注重字符串的转换与匹配。第三次作业需要掌握正则表达式和代码复用,难度最高。2.设计与分析7-2串口字符......
  • PTA题目集阶段总结1
    PTA题目集阶段总结1 前沿概要 第一次写博客还是有点紧张的,毕竟我啥也不会,只能靠一点微薄的知识来支撑本篇文章的高度,在接下来的文章叙述中,如果你看出了些许(也有可能......
  • 算法 - 动态规划
    动态规划技术的核心是“子问题划分”和“记忆化”。比如,leetcode#70.爬楼梯与leetcode#120.三角形最小路径和。#70的子问题划分是这样的----由于每次只能向上爬一个或......
  • 题目集1~3的总结
    前言:前两次大作业题目主要是对java基本语法的考察,例如:基础类型的使用以及String类方法的使用。第三次大作业则开始进入到面向对象程序设计的范畴,考察了类的设计。总体......
  • 数据结构与算法【Java】09---多路查找树
    目录前言1、二叉树与B树1.1、二叉树的问题分析1.2、多叉树1.3、B树的基本介绍2、2-3树2.1、2-3树简介2.2、2-3树应用案例2.3、补充3、B树、B+树和B*树3.1、B树的简......