算法进阶指南:基本算法0x02递归与递推

acwing95:费解的开关

95. 费解的开关 - AcWing题库

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include<bitset>
#include<list> 
#include <algorithm>
#define pii pair<int,int>
#define pll pair<LL,LL>
#define pil pair<int,LL>
#define pli pair<LL,int>
#define pdd pair<db,db>
#define psi pair<string,int>
#define se second 
#define fi first
#define endl '\n'
#define rep(i,a,b) for (register int i=a;i<b;++i)
#define per(i,a,b) for (register int i=a;i>b;--i)
#define MEM(a,x) memset(a,x,sizeof(a))
#define M(x) ((x)%MOD)
#define db double
#define eps 1e-9
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
const int MOD=9901;
const int N=110;
int a[5][5],res,dx[]={0,1,-1,0,0},dy[]={0,0,0,1,-1};
string s[5];
void turn(int x,int y)
{
	++res;
	rep(i,0,5){
		int nx=x+dx[i],ny=y+dy[i];
		if(nx<0||nx>=5||ny<0||ny>=5) continue;
		a[nx][ny]=1-a[nx][ny];
	}
}
bool che()
{
	rep(i,0,5) if(!a[4][i]) return false;
	return true;
}
void solve()
{
	int ans=1e9;
	rep(i,0,5) cin>>s[i];
	rep(i,0,1<<5){
		res=0;
		rep(j,0,5) rep(k,0,5) a[j][k]=s[j][k]-'0';
		rep(j,0,5) if(i>>j&1) turn(0,j);
		rep(j,1,5) rep(k,0,5) if(!a[j-1][k]) turn(j,k);
		if(che()) ans=min(ans,res); 
	}
	if(ans<=6) cout<<ans<<endl;
	else cout<<-1<<endl;
}
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int _=1;
	cin>>_;
	while(_--){
		solve();
	}
	return 0;
}

acwing 96. 奇怪的汉诺塔

96. 奇怪的汉诺塔 - AcWing题库

#include<bits/stdc++.h>
#define endl '\n'
#define rep(i,a,b) for (register int i=a;i<b;++i)
#define per(i,a,b) for (register int i=a;i>b;--i)
#define MEM(a,x) memset(a,x,sizeof(a))
using namespace std;
const int N=15;
int f[N],g[N];
int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    MEM(g,0x3f);
    f[1]=g[1]=1;
    rep(i,2,N) f[i]=2*f[i-1]+1;
    rep(i,2,N) rep(j,1,i) g[i]=min(g[i],2*g[i-j]+f[j]);
    rep(i,1,13) cout<<g[i]<<endl;
    return 0;
}

Fractal Streets

传递门

 

#include<bits/stdc++.h>
#define pii pair<int,int>
#define pll pair<LL,LL>
#define pil pair<int,LL>
#define pli pair<LL,int>
#define pdd pair<db,db>
#define psi pair<string,int>
#define se second 
#define fi first
#define endl '\n'
#define rep(i,a,b) for (register int i=a;i<b;++i)
#define per(i,a,b) for (register int i=a;i>b;--i)
#define MEM(a,x) memset(a,x,sizeof(a))
#define db double
typedef long long LL;
using namespace std;
pll calc(int n,LL m)
{
    if(n==0) return {0,0};
    LL len=1ll<<(n-1),cnt=1ll<<(2*n-2);
    pll p=calc(n-1,m%cnt);
    int k=m/cnt;
    if(k==0) return {p.se,p.fi};
    else if(k==1) return {p.fi,p.se+len};
    else if(k==2) return {p.fi+len,p.se+len};
    else return {2*len-p.se-1,len-p.fi-1};
}
void solve()
{
    int n;
    LL s,d;
    cin>>n>>s>>d;
    --s,--d;
    pll st=calc(n,s),ed=calc(n,d);
    LL x=st.fi-ed.fi,y=st.se-ed.se;
    printf("%.0lf\n",sqrt(x*x+y*y)*10);
}
int main()
{
	//ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int _=1;
	cin>>_;
	while(_--){
		solve();
	}
	return 0;
}

【基于QT的调色板】是一个使用Qt框架开发的色彩选择工具,类似于Windows操作系统中常见的颜色选取器。Qt是一个跨平台的应用程序开发框架,广泛应用于桌面、移动和嵌入式设备,支持C++和QML语言。这个调色板功能提供了横竖两种渐变模式,用户可以方便地选取所需的颜色值。 在Qt中,调色板(QPalette)是一个关键的类,用于管理应用程序的视觉样式。QPalette包含了一系列的颜色角色,如背景色、前景色、文本色、高亮色等,这些颜色可以根据用户的系统设置或应用程序的需求进行定制。通过自定义QPalette,开发者可以创建具有独特视觉风格的应用程序。 该调色板功能可能使用了QColorDialog,这是一个标准的Qt对话框,允许用户选择颜色。QColorDialog提供了一种简单的方式来获取用户的颜色选择,通常包括一个调色板界面,用户可以通过滑动或点击来选择RGB、HSV或其他色彩模型中的颜色。 横渐变取色可能通过QGradient实现,QGradient允许开发者创建线性或径向的色彩渐变。线性渐变(QLinearGradient)沿直线从一个点到另一个点过渡颜色,而径向渐变(QRadialGradient)则以圆心为中心向外扩散颜色。在调色板中,用户可能可以通过滑动条或鼠标拖动来改变渐变的位置,从而选取不同位置的颜色。 竖渐变取色则可能是通过调整QGradient的方向来实现的,将原本水平的渐变方向改为垂直。这种设计可以提供另一种方式来探索颜色空间,使得选取颜色更为直观和便捷。 在【colorpanelhsb】这个文件名中,我们可以推测这是HSB(色相、饱和度、亮度)色彩模型相关的代码或资源。HSB模型是另一种常见且直观的颜色表示方式,RGB或CMYK模型不同,它以人的感知为基础,更容易理解。在这个调色板中,用户可能可以通过调整H、S、B三个参数来选取所需的颜色。 基于QT的调色板是一个利用Qt框架和其提供的色彩管理工具,如QPalette、QColorDialog、QGradient等,构建的交互式颜色选择组件。它不仅提供了横竖渐变的色彩选取方式,还可能支持HSB色彩模型,使得用户在开发图形用户界面时能更加灵活和精准地控制色彩。
标题基于Spring Boot的二手物品交易网站系统研究AI更换标题第1章引言阐述基于Spring Boot开发二手物品交易网站的研究背景、意义、现状及本文方法创新点。1.1研究背景意义介绍二手物品交易的市场需求和Spring Boot技术的适用性。1.2国内外研究现状概述当前二手物品交易网站的发展现状和趋势。1.3论文方法创新点说明本文采用的研究方法和在系统设计中的创新之处。第2章相关理论技术介绍开发二手物品交易网站所涉及的相关理论和关键技术。2.1Spring Boot框架解释Spring Boot的核心概念和主要特性。2.2数据库技术讨论适用的数据库技术及其在系统中的角色。2.3前端技术阐述后端配合的前端技术及其在系统中的应用。第3章系统需求分析详细分析二手物品交易网站系统的功能需求和性能需求。3.1功能需求列举系统应实现的主要功能模块。3.2性能需求明确系统应满足的性能指标和安全性要求。第4章系统设计实现具体描述基于Spring Boot的二手物品交易网站系统的设计和实现过程。4.1系统架构设计给出系统的整体架构设计和各模块间的交互方式。4.2数据库设计详细阐述数据库的结构设计和数据操作流程。4.3界面设计实现介绍系统的界面设计和用户交互的实现细节。第5章系统测试优化说明对系统进行测试的方法和性能优化的措施。5.1测试方法步骤测试环境的搭建、测试数据的准备及测试流程。5.2测试结果分析对测试结果进行详细分析,验证系统是否满足需求。5.3性能优化措施提出针对系统性能瓶颈的优化建议和实施方案。第6章结论展望总结研究成果,并展望未来可能的研究方向和改进空间。6.1研究结论概括本文基于Spring Boot开发二手物品交易网站的主要发现和成果。6.2展望改进讨论未来可能的系统改进方向和新的功能拓展。
1. 用户权限管理模块 角色管理: 学生:查看个人住宿信息、提交报修申请、查看卫生检查结果、请假外出登记 宿管人员:分配宿舍床位、处理报修申请、记录卫生检查结果、登记晚归情况 管理员:维护楼栋房间信息、管理用户账号、统计住宿数据、发布宿舍通知 用户操作: 登录认证:对接学校统一身份认证(模拟实现,用学号 / 工号作为账号),支持密码重置 信息管理:学生完善个人信息(院系、专业、联系电话),管理员维护所有用户信息 权限控制:不同角色仅可见对应功能(如学生无法修改床位分配信息) 2. 宿舍信息管理模块 楼栋房间管理: 楼栋信息:名称(如 "1 号宿舍楼")、层数、性别限制(男 / 女 / 混合)、管理员(宿管) 房间信息:房间号(如 "101")、户型(4 人间 / 6 人间)、床位数量、已住人数、可用状态 设施信息:记录房间内设施(如空调、热水器、桌椅)的配置完好状态 床位管理: 床位编号:为每个床位设置唯一编号(如 "101-1" 表示 101 房间 1 号床) 状态标记:标记床位为 "空闲 / 已分配 / 维修中",支持批量查询空闲床位 历史记录:保存床位的分配变更记录(如从学生 A 调换到学生 B 的时间原因) 3. 住宿分配调整模块 住宿分配: 新生分配:管理员导入新生名单后,宿管可按专业集中、性别匹配等规则批量分配床位 手动分配:针对转专业、复学学生,宿管手动指定空闲床位并记录分配时间 分配结果公示:学生登录后可查看自己的宿舍信息(楼栋、房间号、床位号、室友列表) 调整管理: 调宿申请:学生提交调宿原因(如室友矛盾、身体原因),选择意向宿舍(需有空位) 审批流程:宿管审核申请,通过后执行床位调换,更新双方住宿信息 换宿记录:保存调宿历史(申请人、原床位、新床位、审批人、时间) 4. 报修安全管理模块 报修管理: 报修提交:学生选择宿舍、设施类型(如 "
<think>嗯,用户想了解梅森旋转算法如何生成伪随机数,以及它的原理和实现。首先,我需要回忆梅森旋转算法基本结构。记得它基于线性反馈移位寄存器(LFSR),但具体是怎么操作的? 梅森旋转算法的核心是使用一个大的状态数组,并通过某种递归关系来更新状态。比如MT19937,它的周期是2^19937-1,这个名字也来源于梅森素数。那状态数组的大小应该是624个32位整数,对吗?每个周期处理这624个状态,然后生成新的状态。 接下来,生成随机数的过程。当状态数组被初始化后,每次生成一个随机数的时候,会从当前的状态中提取,并经过一些处理,比如位移和掩码操作。可能涉及到“扭转”(twist)过程,当所有状态都被使用后,需要重新生成新的状态数组,这就是所谓的扭转步骤。 那具体怎么实现的呢?初始化的时候,需要种子,然后根据种子填充状态数组。种子可以是单个整数,或者数组。填充方法可能使用一个递推公式,比如用前一个状态的值经过一些运算得到下一个值。比如,可能用异或、乘法和其他位操作。 然后是状态更新。每次生成一定数量的随机数后(比如624次),需要执行扭转操作。这个步骤可能涉及到将状态数组中的元素进行某种线性变换,可能包括左移、右移、掩码异或等操作。比如,每个元素可能会被分解成高位和低位,然后低位经过变换后高位结合,生成新的状态值。 在生成随机数的时候,每个状态元素会被进一步处理,比如通过右移、左移,不同的掩码异或,最后可能还有一个乘法或加法步骤,以提高分布的均匀性。比如,MT19937的tempering步骤,包括位移和掩码操作,将状态中的数值打乱,生成最终的随机数。 用户可能需要具体的代码示例。这时候,我需要回忆Python中可能的实现方式。比如,状态数组的初始化,扭转函数的实现,以及如何从状态中提取随机数。要注意位操作的正确性,尤其是32位截断,可能需要使用掩码0xFFFFFFFF来保持数值在32位范围内。 另外,需要考虑梅森旋转算法的优缺点。比如,长周期和高维均匀分布,但状态空间较大,初始化较慢,不适合短随机数需求。还有,像种子必须正确初始化,否则可能影响随机性。 可能用户的问题还包括如何优化,或者其他算法比较,但当前问题主要集中在原理和实现上。需要确保解释清晰,分步骤说明初始化、状态更新、随机数生成的各个阶段,并给出代码示例。同时,引用提供的参考资料中的内容,比如MT19937的参数和优点,来支持回答的正确性。 现在需要检查是否有错误的地方。比如,状态数组的大小是否正确,扭转的触发条件是否是索引到达数组末尾,以及tempering步骤的具体操作是否准确。此外,代码中的位操作是否正确处理了32位整数,避免溢出或错误计算。确保示例代码能够正确演示梅森旋转的关键步骤,即使可能简化了某些部分,但核心逻辑正确。</think>梅森旋转算法(Mersenne Twister)是一种基于线性反馈移位寄存器的伪随机数生成算法,其核心原理是通过二进制矩阵的线性递归操作生成均匀分布的数值序列。以下是其原理和实现的分步说明: --- ### **一、算法核心原理** 1. **状态数组结构** 算法维护一个长度为$n$的状态数组(MT19937中$n=624$),每个元素为32位整数,通过递归公式更新状态: $$x_{k+n} = x_{k+m} \oplus \left( (x_k^{\text{u}} \mid x_{k+1}^{\text{l}} ) \cdot A \right)$$ 其中$A$是常数矩阵,$\oplus$表示异或,$x^{\text{u}}$和$x^{\text{l}}$分别表示高低位截断[^3]。 2. **扭转(Twist)操作** 当状态数组遍历完毕后,通过非线性变换生成新状态,确保周期达到$2^{19937}-1$。变换包括位掩码、位移和矩阵乘法。 3. **输出处理(Tempering)** 从状态中提取数值后,需经过以下步骤增强分布均匀性: $$y = x \oplus ((x >> u) \& d)$$ $$y = y \oplus ((y << s) \& b)$$ $$y = y \oplus ((y << t) \& c)$$ $$y = y \oplus (y >> l)$$ 其中$u,s,t,l,d,b,c$为预设常数[^1]。 --- ### **二、Python实现示例** ```python class MersenneTwister: def __init__(self, seed): self.index = 624 self.MT = [0] * 624 self.MT[0] = seed for i in range(1, 624): self.MT[i] = 0xFFFFFFFF & (1812433253 * (self.MT[i-1] ^ (self.MT[i-1] >> 30)) + i) def extract_number(self): if self.index >= 624: self.twist() y = self.MT[self.index] y ^= (y >> 11) y ^= (y << 7) & 0x9D2C5680 y ^= (y << 15) & 0xEFC60000 y ^= (y >> 18) self.index += 1 return 0xFFFFFFFF & y def twist(self): for i in range(624): x = (self.MT[i] & 0x80000000) + (self.MT[(i+1)%624] & 0x7FFFFFFF) self.MT[i] = self.MT[(i+397)%624] ^ (x >> 1) if x % 2 != 0: self.MT[i] ^= 0x9908B0DF self.index = 0 ``` #### **代码说明** - **初始化**:通过种子生成初始状态数组,使用递推公式确保多样性。 - **扭转函数**:通过位移和异或操作更新全部624个状态值。 - **输出处理**:通过四次位移和掩码操作优化数值分布。 --- ### **三、算法特性** | 特性 | 说明 | |--------------------|----------------------------------------------------------------------| | 周期长度 | $2^{19937}-1$,适用于长期连续随机数需求[^2] | | 高维均匀分布 | 在623维空间内均匀分布,适用于蒙特卡洛模拟 | | 局限性 | 状态空间较大(2.5KB),初始化速度慢于线性同余法 | --- ### **四、对比其他算法** - **线性同余法**:周期短(通常$2^{32}$),易预测,但实现简单。 - **Xorshift**:轻量快速,但周期和分布质量低于梅森旋转。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值