蓝桥杯递推与递归法|斐波那契数列|数字三角形|42点问题|数的计算|数的划分(C++)

news2024/10/1 1:16:31
递归是用来做dfs,是搜索算法的基础
递推是用来做dp部分,及部分其他算法,复杂度较低,不会出现爆栈问题

递推法:

递推法是一种在数学和其他领域广泛应用的重要方法,它在计算机科学中被用作一种关键的数值求解算法。

递推算法的特点

递推法的核心在于找到递推关系式。这种方法可以将复杂的计算过程转化为简单的重复步骤,充分利用计算机在运行程序时的时间局部性和空间局部性。

递推算法的思想:
  1. 首先找到各个相邻数据项之间的递推关系;
  2. 递推关系避开了求通项公式的麻烦,尤其是对于那些难以或无法求解通项公式的题目;
  3. 将复杂问题分解为若干步骤的简单运算;
  4. 一般来说,递推算法可以视为一种特殊的迭代算法。
递推算法解题的基本思路:
  1. 将复杂计算转换为简单重复运算;
  2. 通过找到递推关系式进行简化运算;
  3. 利用计算机的特性,减少运行时间。
递推算法的一般步骤:
  1. 根据题目确定数据项,并找到符合要求的递推关系式;
  2. 根据递推关系式设计递推程序;
  3. 根据题目找到递推的终点;
  4. 单次查询可以不进行存储,多次查询都要进行存储;
  5. 按要求输出答案即可。

递归法

递归算法:

递归算法是一种自顶向下的算法,它通过不断地直接或间接调用自身的函数,通过每次改变变量完成多个过程的重复计算,直到到达边界之后,结束调用。
与递推法相似的是,递归与递推都是将一个复杂过程分解为几个简单重复步骤进行计算。
递归算法的实现的核心是分治策略,即分而治之,将复杂过程分解为规模较小的同类问题,通过解决若干个小问题,进而解决整个复杂问题。

递归算法的思想:
  1. 将复杂计算过程转换为简单重复子过程;
  2. 找到递归公式,即能够将大问题转化为小问题的公式;
  3. 自上而下计算,在返回完成递归过程。
递归算法设计的一般步骤:
  1. 根据题目设计递归函数中的运算部分;
  2. 根据题目找到递归公式,题目可能会隐含给出,也可能需要自己进行推导;
  3. 找到递归出口,即递归的终止条件。

递归法和递推法的思路已经给大家讲解得差不多了,接下来我们将结合真实的大赛题目进行讲解。这将有助于我们更好地理解和应用这两种方法。

1. 斐波纳契数列 fibonacci 问题

在一定情况下,同一个问题可以使用用递归也可以使用递推解答。一般一个问题的递推关系和递归关系都好求的话就都可以解题。
当然如果题目只有一个关系好求,那就最好采用关系好求的办法。
题目描述:
斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”。

指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、…

在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1,F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N^*)

请求出该数列中第n个数字(n从1开始计数)是多少。

样例:

输入样例
样例1输入
6
样例2输入
4
输出样例
样例1输出
8
样例2输出
3

对于上面的样例我们进行了如下计算;

[0]=0
[1]=1
[2]=0+1
[3]=1+1=2
[4]=1+2=3
[5]=2+3=5
[6]=5+3=8

运行限制:

1. 最大运行时间:1s
2. 最大运行内存:128M

题目解析:

  • 这个题给出递推式 F(n) = F(n-1) + F(n-2)
  • 转化为可用的递推关系,即F(n) + F(n+1) = F(n+2)
    这一通过从n=1开始循环即可完成递推,当然也可以使用递归法。

首先我们写找出递归式,F(n)= F(n-1) + F(n-2)

F(n)= F(n-1) + F(n-2)
    = F(n-2)+F(n-3)+F(n-3)+F(n-4)
//重复调用

这样我们找到了递归式,然后我们应该找到递归出口。
我们可以知道 F(n)=0 n=0 ,F(n)=1 n=1这就是递归出口,能让递归停止的条件。
递归算法的通用框架如下:

do(a,b,c...)
{
    //递归终止条件,即出口
    if(a==? ,b==? ,....) return

    //递归条件
    if(条件1)
        do(参数1)

    else(条件2)
        do(参数2)

}

如本题,各子式间存在计算关系,可以化为:

do(a)
{
    if(a==0) return 0;
    if(a==1) return 1;

    return do(a-1)+do(a-2);
}

这道题不是多次询问问题,不需要存储直接计算的复杂度是最低的。

答案解析

C++ 代码:

  • 递推算法代码
#include <iostream>
using namespace std;

int main()
{
    int n; //第几个数
    int x=0; //F(n)
    int y=1; //F(n+1)
    int ans; //F(n+2)

    cin>>n;

    if(n==0) ans=0;
    else if(n==1) ans=1;
    else {
        for(int i=2;i<=n;i++)
        {
            ans=x+y;
            x=y;
            y=ans;
        }
    }
    cout<<ans<<endl;

}
  • 递归算法代码

#include <iostream>
using namespace std;

int fn(int n)
{
    //递归出口1
    if(n==0)
        return 0;

    //递归出口2
    else if(n==1 )
        return 1;

    else
        return fn(n-1)+fn(n-2); //递归关系式
}


int main()
{

    int n; //第几个数
    int ans;

    cin>>n;

    ans=fn(n);

    cout<<ans<<endl;

}
改进:记忆化

递归过程中做了重复工作,例如fib(3)计算了两次,其实只算1次就够了
为避免递归时重复计算,可以在子问题得到解决时,就保存结果,再次需要这个结果时,直接返回保存的结果就行了,不继续递归下去
这种存储已经解决的子问题结果的技术称为记忆化
记忆化是递归的常用优化技术
动态规划也常常使用递归写代码,记忆化也是动态规划的关键技术

#include <bits/stdc++.h>
using namespace std;

int cnt = 0;    //统计执行了多少次递归
int data[25];   //存储斐波那契数
int fib (int n)
{
	cnt++;
	if (data[n] != 0)   //记忆化搜索,已经算过,不用再算,直接返回结果
		return data[n];
	if (n == 1 || n == 2)
	{
		data[n] = 1;
		return data[n];
	}
	data[n] = fib(n - 1) + fib(n - 2);   //继续递归
	return data[n];
}
int main()
{
	cout << fib(20);         //计算递20个斐波那契数
	cout << " cnt=" << cnt;  //递归了cnt = 37次
}
存储型的递推与递归

我们在开始就讲过题目十分存储和非存储的,上面那个题目就是此询问,如果改为多次询问我们该怎么办,我们会采用存储的方式,存储的方式适用于大部分的的多次查询问题。
我们看一下修改后的题目。

题目描述:

斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”。

指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……
在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1,F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)
我们将进行M次查询,每次输入一个N,其中n小于30。
请求出该数列中第n个数字(n从1开始计数)是多少?

样例:
输入样例
样例1输入:
	6
	4
	2
	7
	8
	8
	10
样例2输入:
	8
	13
	23
	14
	17
	24
	16
	10
	11
输出样例
样例1输出:
	3
	1
	13
	21
	21
	55
样例2输出:
	233
	28657
	377
	1597
	46368
	987
	55
	89

运行限制:

1. 最大运行时间:1s
2. 最大运行内存:128M
题目解析:

这道题跟上面一道题的算法原理相同,只是增加了多次查询的复杂度,所以仅需修改这一点即可。
再有的是有的同学担心自己的输入输出是在一个屏幕上的,评测的时候会不会出现问题。
类似这样的情况,这一点是不用担心的,只要不是交互题,评测机的输入与输出是分开的,只有你的输出会用来跟答案比较,所以我们只用关心我们的输出即可。
比如有一道题让你计算 x+y 的值,如果你知道每答案,就可以直接输出,都不用进行读入。

然后我们来看一下需要多次询问的题目该怎么解决。

答案解析
C++ 代码:
递推算法代码

#include <iostream>
using namespace std;
int F[35];

void init()
{
    F[0]=0;
    F[1]=1;
    for(int i=2;i<=30;i++)
    {
        F[i]=F[i-1]+F[i-2];
    }
}
int main()
{
    int m; //m次查询
    int n; //第几个数
    init();

    cin>>m;

    while(m>0)
    {
        m-=1;
        cin>>n;
        cout<<F[n]<<endl;
    }
}

存储答案的递推法,才是最常使用的递推法。

递归算法代码

#include <iostream>
using namespace std;
int F[35];

int fn(int n)
{
    //递归出口1
    if(n==0)
    {
        F[0]=0;
        return 0;
    }

    //递归出口2
    else if(n==1 )
    {
        F[1]=1;
        return 1;
    }

    else
    {
        F[n]=fn(n-1)+fn(n-2);
        return F[n]; //递归关系式
    }
}

int main()
{
    int m; //m次查询
    int n; //第几个数

    fn(30);
    cin>>m;

    while(m>0){
        m-=1;
        cin>>n;
        cout<<F[n]<<endl;
    }
}
数字三角形问题

题目描述:
图片描述
如图数字三角形。如下所示为一个数字三角形。请编一个程序计算从顶到底的某处的一条路径,使该路径所经过的数字总和最大。只要求输出总和。

  1. 一步可沿左斜线向下或右斜线向下走;
  2. 三角形行数小于等于 100;
  3. 三角形中的数字为 0,1,…,99;
    测试数据通过键盘逐行输入。
    如上例数据应以样例所示格式输入:
    样例:
输入:
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输出:
30

运行限制:

1. 最大运行时间:1s
2. 最大运行内存:128M

题目分析:
N=100,
S= ( 1 + 100 ) ∗ 100 = 1 0 4 (1+100)*100=10^4 (1+100)100=104
量级是 1 0 4 10^4 104,每个数都是0-99
最后是 1 0 6 10^6 106,用暴力也能做出来

解决该题目的方式有很多,包括动态规划, 枚举都可以解决这个问题。

我们从递推的思想出发,假设我们从顶层沿着某条路径已经走到了第 i 层,正向着 i+1 层前进, 两条可行路径中我们肯定会选择最大的方向前进,
为此我们可以采用递推中的反向递推,即逆推的方式解决,设 a [ i ] [ j ] a[i][j] a[i][j]存放从 i , j i,j i,j 出发到达第 n n n 层的最大值。
我们可以写出递推式:

a[i][j] = max{a[i][j]+a[i+1][j],a[i][j]+a[i+1][j+1]}

则 逆推到出发点 a [ 1 ] [ 1 ] a[1][1] a[1][1]为题目所求答案,即第一层到第 N N N层的最大值。
递推一层由

7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

逆推第一层

7
3 8
8 1 0
7 12 10 10

第二层

7
3 8
20 13 10

第三层

7
23 21

第四层

30

递推的每次计算是 O ( 1 ) O(1) O(1) i i i是层数, j j j i i i层的这几个

C++ 代码:
#include<iostream>
using namespace std;

int main()
{
    int n; //n层
    int a[101][101]; //路径矩阵
    cin>>n;

    //输入数字三角形的值
    for (int i=1; i<=n; i++)
    {
        for (int j=1; j<=i; j++)
        {

        cin>>a[i][j]; //输入原始数据

        }
    }

    //递推开始

    for (int i=n-1; i>=1; i--)//从最后一层逆推
    {
        for (int j=1; j<=i; j++)
        {

            if (a[i+1][j]>=a[i+1][j+1])
                a[i][j]+=a[i+1][j];     //路径选择
            else
                a[i][j]+=a[i+1][j+1];
        }
    }

    cout<<a[1][1]<<endl;
}

递推法的推广

42点问题
题目描述

众所周知在扑克牌中,有一个老掉牙的游戏叫做 24 点:选取4 张牌进行加减乘除,看是否能得出 24 这个答案。
现在小蓝同学发明了一个新游戏,他从扑克牌中依次抽出6张牌(注意不是一次抽出),进行计算,看是否能够组成 42 点,满足输出 YES,反之输出 NO。
最先抽出来的牌作为第一个操作数,再抽出牌做第二个操作数,运算结果再当作第一个操作数,继续进行操作。除不尽的情况保留整数。
请你设计一个程序对该问题进行解答。

输入描述
输出仅一行包含 6 个字符。
保证字符∈3 4 5 6 7 8 9 10 J Q K A 2。

输出描述
若给出到字符能够组成 42 点,满足输出 YES,反之输出 NO。

题目解析

不是一次抽出,可以重复,有放回事件

数据输入

for (int i = 0; i < 6; i++)
{
	char c;
	cin >> c;
	if (c == 'A')
		a[i] = 1;

	else if (c == 'J')
		a[i] = 11;
	else if (c == 'Q')
		a[i] = 12;
	else if (c == 'K')
		a[i] = 13;

	else
		a[i] = (c - '0');
}

怎么枚举5次运算
共计 4 ∗ 4 ∗ 4 ∗ 4 ∗ 4 = 1024 4*4*4*4*4=1024 44444=1024种情况
创建5个vector,分别用来存放1-5次的运算结果

vector <int> ans[10];
ans[0].push_back(a[0]);

for (int i = 1; i <= 5; i++)
{
	for (int j = 0; j < ans[i-1].size(); j++)
	{
		ans[i].push_back(ans[i-1][j]+a[i]);
		ans[i].push_back(ans[i-1][j]-a[i]);
		ans[i].push_back(ans[i-1][j]*a[i]);
		ans[i].push_back(ans[i-1][j]/a[i]);
	}
	
}

判断

int flag = 0;

for (int i = 0; i < ans[5].size(); i++)
{
	if (ans[5][i] == 42)
	{
		flag = 1;
		break;
	}
}
if (flag == 1)
	cout << "YES" << endl;
else
	cout << "NO" << endl;
数的计算
题目描述

我们要求找出具有下列性质数的个数(包含输入的自然数 n):
先输入一个自然数 n ( n ≤ 1000 ) n(n \le 1000) n(n1000),然后对此自然数按照如下方法进行处理:

  1. 不作任何处理:
  2. 在它的左边加上一个自然数,但该自然数不能超过原数的一半:
  3. 加上数后,继续按此规则进行处理,直到不能再加自然数为止。
    例:n=6,合法的数字有:6(不做任何处理)、16、26、36、126、136
题目解析

第一层递归,枚举 a = 1 , 2 , … , n 2 a=1,2,\dots,{\frac{n}{2}} a=1,2,,2n
第二层递归,枚举 b = 1 , 2 , … , a 2 b=1,2,\dots,{\frac{a}{2}} b=1,2,,2a
第三层递归,枚举 c = 1 , 2 , … , b 2 c=1,2,\dots,{\frac{b}{2}} c=1,2,,2b

最后一层,等于1,返回


6
6/2=3 构造出 16 26 36
再根据16,a=1 构造不出来了,1/2=0
再根据26,a=2 构造2/2=1,构造出126
再根据126,1/2=0,构造不出来了
再根据36,构造3/2=1,构造出136
136不能再产出新数字


void f (int n)
{
	if (n == 1)
		return;   //如果n = 1,满足条件的数的个数是1
	for (int i = 1; i <= n/2; i++)  //枚举左边加的数
	{
		res++;   //新得到一个数,满足条件的数的个数+1
		f(i);    //递归
	}
}

按照题目意思,我们可以直接枚举左边加的数。
定义递归函数 f(n)表示输入数为 n 时满足题目条件的数的个数。
我们可以从最简单的情况开始考虑。当n =1时,只有一个数,满足条件的数的个数是 1。
如果 n > 1,那么我们需要枚举左边加的数。因为最左边的数不能为 0,所以左边加上的数的取值范围是 [ 1 , n / 2 ] [1,{n/2}] [1,n/2]
对于每一个加数i,得到的新数是n+i,我们需要递归调用 f(n +i),计算得到新数下满足条件的数的个数。
在递归调用结束后,我们需要将所有加数得到的满足条件的数的个数相加,得到最终的结果。
最后,输出 f(n)即可。

N=1时,1/2=0,无法进行构造,就只有一个解
N=2时,2/2=1,恰好构造出了12和本身2
N=3时,3/2=1,恰好构造出了13和本身3
N=4时,4/2=2,能够构造出14 24 124 4
如果写成函数

f(4) = f(4/2=2)+f(2/2=1)+1   //124 24 / 14 / 4
f(5) = f(5/2=2)+f(2/2=1)+1   //125 25 / 15 / 5
...
f(n) = f(n/2)+f(n/2/2)+...+f(1)+1

递归式:

F(n):
	用i=(1-n/2)构造;
		对于每个生成的新的i,再次调用f(i)
		每构造一次就+1
代码
#include <iostream>
using namespace std;

int f[1000];
int main()
{
	int n;
	scanf("%d", n);

	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= i/2; j++)
		{
			f[i] = f[i] + f[j];
		}
		f[i] = f[i] + 1;
	}

	return 0;
}
数的划分
题目描述

将整数 n 分成k份,且每份不能为空,任意两份不能相同(不考虑顺序)。
例如:n=7,k=3,下面三种分法被认为是相同的。
1,1,5;
1,5,1;
5,1,1;
问有多少种不同的分法。
输入描述
输入一行,2 个整数 n,k (6 ≤n≤ 200,2 ≤k≤ 6)。
输出描述
输出一个整数,即不同的分法


题目解析

计数dp,分治思想
7
4,2,1
定义递归函数 f ( n , m ) f(n,m) f(n,m)为将整数 n 拆分成 m 个数字的方案数。
对于每个情况,我们可以将它分成两种情况,且这两种情况是不重不漏的。

  1. 不选1的情况
    如果不选择 1,我们将 n 拆分成 m 块,可以等价于将每一块都减去 1,然后再将剩下的数拆分成m块,即 f ( n − m , m ) f(n-m,m) f(nm,m)
  2. 选1的情况:
    这种情况下,其中一块肯定有一个 1,然后对几-1拆分成 m-1块,即 f ( n − 1 , m − 1 ) f(n-1,m-1) f(n1,m1)
    此时, f ( n , m ) f(n,m) f(n,m)的值就是这两种情况之和,即
    f ( n , m ) = f ( n − m , m ) + f ( n − 1 , m − 1 ) f(n,m)=f(n-m,m)+f(n-1,m-1) f(n,m)=f(nm,m)+f(n1,m1)

对于样例7分3份:

  1. 不选1,那就先每份给个1
    111剩下了4,由于不选1,所以每组还得再分至少一个,所以就变成 f ( n − m , m ) f(n-m,m) f(nmm),即 7 − 3 = 4 7-3=4 73=4分成3份 f ( 4 , 3 ) f(4,3) f(4,3)
    对于 f ( 4 , 3 ) f(4,3) f(4,3)在考虑递归过程,同样分两种情况
    1. f ( 4 , 3 ) = f ( 4 − 3 , 3 ) + f ( 4 − 1 , 3 − 1 ) f(4,3)=f(4-3,3)+f(4-1,3-1) f(4,3)=f(43,3)+f(41,31)
      1. f(1,3)不合理,所以没有这种可能返回0
      2. f ( 3 , 2 ) = f ( 3 − 2 , 2 ) + f ( 3 − 1 , 2 − 1 ) f(3,2)=f(3-2,2)+f(3-1,2-1) f(3,2)=f(32,2)+f(31,21)
        1. f ( 1 , 2 ) f(1,2) f(1,2)不合理返回0
        2. f ( 2 , 1 ) f(2,1) f(2,1)两个数分成1堆,只有一种办法返回1
  2. 选1的情况,有且只能有1个1,所以1那个位置就不再改变,我们就去考虑剩下的7-1个数,分成3-1份,那就变成了 f ( n − 1 , m − 1 ) f(n-1,m-1) f(n1,m1) f ( 6 , 2 ) f(6,2) f(6,2)
    对于 f ( 6 , 2 ) f(6,2) f(6,2)使用同样的递归过程继续执行
代码
#include <bits/stdc++.h>
using namespace std;

int f(int n, int m)
{
	if (n == 0 || m == 0 || n < m)
	{
		return 0;
	}
	if (m == 1 || n == m)
	{
		return 1;
	}
	else
	{
		return f (n - m, m) + f(n - 1, m - 1);
	}
}

int main()
{
	int n, k;
	cin >> n >> k;
	cout << f (n, k) << "\n";
	return 0;
}
过多分支的一种处理思路
题目描述

古代中国使用天干地支来记录当前的年份。
天千一共有十个,分别为:甲、乙、丙、丁、戊、己、庚、辛、王、癸 。地支一共有十二个,分别为:子、丑、寅、卯、辰、日、午、未、申、酉、戌、亥将天干和地支连起来,就组成了一个天干地支的年份,例如:甲子。
2020 年是庚子年。
每过一年,天干和地支都会移动到下一个。例如2021年是辛丑年。
每过 60年,天千会循环6轮,地支会循环5轮,所以天干地支纪年每 60年轮回一次。例如 1900年,1960年,2020年都是庚子年给定一个公元纪年的年份,请输出这一年的天干地支年份。

输入描述

输入一行包含一个正整数,表示公元年份。
其中有 ,输入的公元年份为不超过9999的正整数。

输出描述

输入一行包含一个正整数,表示公元年份。


这个题目是模拟法中最讨厌也最常见的一种,可能还有比这更复杂的,但这道题,已经初具代表性
他的种类比较多,天干就有10种,地支有12种
现在我们知道了 2020年是庚子年,我们这里既可以是除留余数来判断N年是什么天干和什么地支,我们也可以直接暴力使用循环做,这样的话9999的复杂度也跑不了多久。
实现起来很简单,我们讲这个比较难的。
我们先判断0000年的天干和地支
根据题意8000年距2020年了2020年。
已知天干有10个,那么2020%10=0剩下的都是整个轮回,即到了0000年是庚X年,即天干是庚,
再按照这个方法算地支是2020%12=4及还要向前推四年地支为申。
即 0000 为申年,那么根据模拟法可知。

string tg(int n)
{
	n = n%10;
	if (n == 0)
		return "geng";
}
string dz(int n)
{
	...
}
string tg[10] = {"geng"."xin","ren","gui","jia","yi","bing","ding","wu","ji"};
string dz[12] = {"shen","you","xu","hai","zi","chou","yin","mou","chen","si","wu","wei"};

int main()
{
	int year;
	cin >> year;
	cout << tg[year%10] << dz[year%12] << endl;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1505793.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【深度学习笔记】6_10 双向循环神经网络bi-rnn

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;部分标注了个人理解&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 6.10 双向循环神经网络 之前介绍的循环神经网络模型都是假设当前时间步是由前面的较早时间步的序列决定的&#xff0c;因此它们都将信…

Java宝典-抽象类和接口

目录 1. 抽象类1.1 抽象类的概念1.2 抽象类的语法1.3 抽象类的特点 2. 接口2.1 接口的概念2.2 接口的语法2.3 接口的特点2.4 实现多个接口2.5 接口的继承 3. 接口使用案例 铁汁们好,今天我们学习抽象类和接口~ 1. 抽象类 1.1 抽象类的概念 什么是抽象类?在面向对象中,如果一…

cmaketool插件的自动扫描工作空间设置

点击左下角的齿轮&#xff0c;进入设置。 搜索cmake&#xff1a;config 将不需要的取消打钩即可

CCF-A推荐会议 安全界顶会ACM CCS‘24 4月29日第二轮投稿!共建更安全的数字世界!

会议之眼 快讯 第31届ACM CCS (ACM Conference on Computer and Communications Security)即计算机和通信安全会议将于 2024 年 10月14日-18日在美国盐湖城举行&#xff01;CCS是美国计算机协会(ACM)安全、审计与控制特别兴趣小组(SIGSAC)主办的一年一度的重要会议。是SIGSAC的…

Redisson学习

简介 Redisson 是一个在 Redis 的基础上实现的 Java 驻留内存数据网格&#xff08;In-Memory Data Grid&#xff09;。它提供了许多分布式 Java 对象和服务&#xff0c;包括分布式锁、分布式集合、分布式执行服务、分布式调度任务等。 使用 依赖 相关依赖&#xff0c;注意版…

【Attribute】Inspector视图可视不可编辑字段特性

简介 在Unity开发中&#xff0c;有时候我们存在这种需求&#xff0c;需要在Inspector视图中可以查看字段信息但是无法对字段进行赋值&#xff0c;那么我们也可以像Unity内置的[SerializeField]、[Tooltip]等特性那样自定义一个特性&#xff0c;用于满足这个需求。 代码示例(C#…

【备战蓝桥杯系列】蓝桥杯国二选手笔记二:算法模版笔记(Java)

感谢大家的点赞&#xff0c;关注&#xff0c;评论。准备蓝桥杯的同学可以关注一下本专栏哦&#xff0c;不定期更新蓝桥杯笔记以及经验分享。本人多次参加过蓝桥杯&#xff0c;并获得过蓝桥杯国二的成绩。 算法模版笔记&#xff08;Java&#xff09; 这篇文章给大家分享我的蓝桥…

【C++】二叉树进阶之二叉搜索树

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;熟练掌握二叉搜索树&#xff0c;能自己模拟实现二…

每日一题-合成两个有序链表

&#x1f308;个人主页: 会编辑的果子君 &#x1f4ab;个人格言:“成为自己未来的主人~” 以上是题目信息&#xff1a; 下面是解答过程 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ typedef struct Lis…

【C#语言入门】17. 事件详解(上)

【C#语言入门】17. 事件详解&#xff08;上&#xff09; 一、初步了解事件 定义&#xff1a;单词Event&#xff0c;译为“事件” 通顺的解释就是**“能够发生的什么事情”**&#xff0c;例如&#xff0c;“苹果”不能发生&#xff0c;但是“公司上市”这件事能发生。在C#中事…

Android 完整SDK项目中添加对应的JNI与底层通信

安卓应用发消息给底层 近日需要写一个安卓app和底层发消息&#xff0c;这就涉及到java如何到c层的一个逻辑&#xff0c;app已经写好&#xff0c;就差发个消息了。至于如何对接底层&#xff0c;得和写底层的人进一步沟通&#xff0c;本文笔者只写从java层通信到cpp&#xff0c;…

RabbitMQ - 05 - Direct交换机

部署demo项目 通过消息队列demo项目进行练习 相关配置看此贴 http://t.csdnimg.cn/hPk2T 注意 生产者消费者的yml文件也要配置好 什么是Direct交换机 Direct 交换机是 AMQP&#xff08;高级消息队列协议&#xff09;中的一种交换机类型&#xff0c;它根据消息的路由键&am…

【微服务】SpringBoot整合Resilience4j使用详解

目录 一、前言 二、熔断器出现背景 2.1 几个核心概念 2.1.1 熔断 2.1.2 限流 2.1.3 降级 2.2 为什么会出现熔断器 2.3 断路器介绍 2.3.1 断路器原理 三、Resilience4j介绍 3.1 Resilience4j概述 3.1.1 Resilience4j是什么 3.1.2 Resilience4j功能特性 3.2 Resilie…

巨型犰狳优化算法(Giant Armadillo Optimization,GAO)的无人机三维路径规划(MATLAB)

一、无人机路径规划模型介绍 无人机三维路径规划是指在三维空间中为无人机规划一条合理的飞行路径,使其能够安全、高效地完成任务。路径规划是无人机自主飞行的关键技术之一,它可以通过算法和模型来确定无人机的航迹,以避开障碍物、优化飞行时间和节省能量消耗。 二、算法介…

javase day01笔记

第一天课堂笔记 Java第三代高级语言中的面向对象的语言 b/s 浏览器/服务器c/s 客户端/服务端 1991年詹姆斯高斯林在sun公司开发的Java 常用的dos命令 磁盘操作系统&#xff1a;dos win &#xff0b; r -》 cmd dos命令 切换盘符&#xff1a;直接输入对应盘符目录操作&#x…

【R包开发:入门】 简介+ 包的结构

简介 本书的目的是教你如何开发包&#xff0c;以便你可以写出自己的包&#xff0c;而不只是使用别人的包。 为什么要写一个包&#xff1f; 一个令人信服的理由是&#xff0c;你想要与他人分享代码。把你的代码打成一个包&#xff0c;可以方便他人使用&#xff0c;因为他们像你…

vue中性能优化

目录 1. 编码优化 2. 源码优化 3. 打包优化 4. 利用 Vue Devtools 总结 Vue.js 作为一个强大的前端框架&#xff0c;提供了丰富的功能和工具来帮助开发者构建高效的 Web 应用。然而&#xff0c;在开发过程中&#xff0c;性能优化仍然是一个需要关注的问题。以下是对 Vue.j…

高级IO【select、poll、epoll】

高山仰止&#xff0c;景行行止 文章目录 五种IO模型阻塞I/O非阻塞I/OI/O复用信号驱动I/O异步I/O 同步通信与异步通信同步通信异步通信 非阻塞IO基于fcntl实现setNonblock函数注意事项 IO多路转接—select文件描述符集合timeval结构调用过程返回值缺点和局限性 IO多路转接—poll…

Java共享问题 、synchronized 线程安全分析、Monitor、wait/notify

文章目录 1.共享带来的问题1.1 临界区 Critical Section1.2 竞态条件 Race Condition 2. synchronized语法及理解2.1 方法上的 synchronized 3.变量的线程安全分析3.1.成员变量和静态变量是否线程安全&#xff1f;3.2.局部变量是否线程安全&#xff1f;3.2.1 局部变量线程安全分…

三阶导数在生活中应用

“鲍威尔还表示&#xff0c;美联储将在某个时候放慢&#xff08;利率&#xff09;加息步伐” 这是参考三阶导数&#xff08;贷款义务基础&#xff0c;利率一阶导数&#xff0c;利率变化二阶导数&#xff0c;利率变化速度三阶导数&#xff09;。 是否还有其他有趣的例子&#…