省选模拟测试23 T1直径

该文介绍了一种构造直径为k的树的方法,通过构建菊花图并利用边权为0的链,形成特定结构的树。文章提供了具体的算法实现,通过枚举和分解质因数来找到合适的节点数量和边的关系。此外,还讨论了当边权不为0时的解决方案。

题目大意

给你一个数 k k k,请你构造一棵节点数量小于等于 5000 5000 5000且直径数量为 k k k的树。

我们定义这棵树的直径为,所有满足 1 ≤ i < j ≤ n 1\leq i<j\leq n 1i<jn ( i , j ) (i,j) (i,j)中, d i s ( i , j ) dis(i,j) dis(i,j)最大的。如果有多个这样的 ( i , j ) (i, j) (i,j),那么均为直径。

1 ≤ k ≤ 5 × 1 0 6 , 0 ≤ w i ≤ 1 0 5 1\leq k\leq 5\times 10^6,0\leq w_i\leq 10^5 1k5×106,0wi105 w i w_i wi表示第 i i i条边的边权。


题解

构造一个菊花图,根节点有三个儿子,每个儿子所在的子树大小分别为 a , b , c a,b,c a,b,c且都是一条由权值为0的边组成的链,那么直径为 a b + b c + c a ab+bc+ca ab+bc+ca

在这里插入图片描述
我们需要令 k = a b + a c + b c = ( a + c ) ( b + c ) − c 2 k=ab+ac+bc=(a+c)(b+c)-c^2 k=ab+ac+bc=(a+c)(b+c)c2

我们可以枚举 c c c,将 k + c 2 k+c^2 k+c2分解质因数,直到找到合适的 ( a , b , c ) (a,b,c) (a,b,c)即可。

经过计算可以证明有很高的概率存在这样合适的解,实际上对于所有的 k k k都如此。

时间复杂度为 O ( n k ) O(n\sqrt k) O(nk )

当然,还有一种更好的方法,请看我的另一篇博客

code

#include<bits/stdc++.h>
using namespace std;
int n,tot=0,vt=1,fl=0;
struct node{
	int x,y,z;
}w[10005];
void dd(int v){
	for(int i=1;i<=v-1;i++){
		w[++tot]=(node){vt,vt+1};++vt;
	}
}
int main()
{
	scanf("%d",&n);
	for(int a,b,c=1;c<=5000;c++){
		int v=n+c*c;
		for(int i=c;i*i<=v;i++){
			if(v%i>0) continue;
			a=i-c;b=v/i-c;
			if(a>=0&&b>=0&&a+b+c+1<=5000){
				if(a){
					w[++tot]=(node){1,++vt,1};
					dd(a);
				}
				if(b){
					w[++tot]=(node){1,++vt,1};
					dd(b);
				}
				if(c){
					w[++tot]=(node){1,++vt,1};
					dd(c);
				}
				fl=1;break;
			}
		}
		if(fl) break;
	}
	printf("%d\n",vt);
	for(int i=1;i<=tot;i++){
		printf("%d %d %d\n",w[i].x,w[i].y,w[i].z);
	}
	return 0;
}

一些思考

如果 w i w_i wi不能为 0 0 0,怎么办呢?我们把根节点的每个儿子分别设置对应多个儿子,使得这些儿子没有儿子且到其父亲边权为1即可。

在这里插入图片描述

<think>好的,我现在需要解决用户提出的关于船舶操纵运动建模与仿真的复杂问题。这个问题涉及多个步骤,从参数定义、方程建立到编程实现和结果分析。我需要逐步分解每个任务,并确保每个部分都正确无误。 首先,用户要求设计船体参数和航速。我需要参考典型的油轮参数,比如船长、船宽、吃水等。例如,VLCC(超大型油轮)的参数可能合适,所以我会择L=320米,B=60米,吃水T=20米,航速U=15节(约7.72米/秒)。这些参数需要符合常规,确保后续计算的合理性。 接下来是坐标系的定义。通常,船舶运动学使用右手坐标系,原点在船中,X轴向前,Y轴向右,Z轴向下。这样能方便地描述船舶的横荡、纵荡和艏摇运动。对于操纵运动方程,用户要求整体式模型,可以择非线性模型,如Abkowitz模型,或者线性模型如Nomoto模型。这里可能需要简化,比如Nomoto模型的一阶方程,适用于回转和Z形试验,方程形式为T*r_dot + r= K*delta,其中r是艏摇角速度,delta是舵角。不过用户可能希望更全面的三自由度模型,包括横荡、纵荡和艏摇。此时需要引入水动力导数,如X', Y',N'等,构建非线性方程。第三步是根据水动力导数计算K、T、C参数。假设给定的水动力导数包括Yv, Yr, Nv,Nr等。K和T通常来自Nomoto模型,K=K0/(1+T1*s),但可能需要通过水动力导数计算。例如,K = (Nδ / (Nr- Yv*U)),T= (Iz -Nr)/(Yv*Nr - Nv*Yr),但具体公式需要参考船舶操纵性理论。这里可能需要更准确的推导,或者用户是否提供了具体的水动力导数数值?假设用户提供的是类似Yv'=-0.5,Nv'=-0.1,Nr'=-0.2,Yr'=0.3,那么可能需要代入到K和T的计算中。例如,在Nomoto模型中,K = (Yδ * Nv' - Nδ* Yv')/ (Yv' * Nr'- Yr'* Nv'),但具体的公式可能不同,需要确认。 第四步择离散方法,欧拉法比较简单,适合教学示例。例如,对于微分方程dy/dt= f(y,t),用y_{n+1}= y_n +h*f(y_n, t_n)。而龙格-库塔法(如RK4)精度更高,但代码稍复杂。这里用户可能希望择其中一种,比如欧拉法,因为代码更简单,适合快速实现。 第五步是编程实现。用户可以择Python,因为其易用性。需要离散操纵运动方程,例如,对于三自由度模型,将加速度计算出来,然后用欧拉法更新速度和位置。可能需要定义微分方程的函数,然后在时间循环中进行迭代。例如,在每个时间步计算加速度,更新速度,再积分得到位置。第六步是代入水动力导数进行仿真。比如回转试验需要保持舵角为35度(例如),模拟船舶回转轨迹。而Z形试验是舵角交替变化,如10度到-10度,记录艏向角的变化。需要确保舵机速率保持5°/s,即舵角变化率不超过这个值。在代码中,需模拟舵角的改变过程,如当目标舵角变化时,逐步调整,直到达到目标。 第七步是计算特征参数。回转试验的定常回转直径可以通过稳定后的回转轨迹计算。进距、横距等参数需要从轨迹数据中提取。Z形试验的第一超越角是第一个峰值,第二超越角是反向的峰值。 第八步是与IMO规范比较。例如,IMO对回转直径的要求可能不超过5倍船长,或者Z形试验的超越角不超过一定值。需要查阅具体规范数值,进行比较。 第九步是改进操纵性,可能通过调整K、T参数,如增加舵面积,改变船体设计等,然后验证仿真结果是否改善。 现在,我需要整理这些思路,逐步给出每个步骤的具体实现,并确保各部分的衔接正确。例如,在建立运动方程时,可能需要详细列出各力的表达式,再转化为微分方程。在编程时,需处理时间步长,积分方法,以及舵角变化的模拟。 可能遇到的难点包括正确推导运动方程,处理非线性项,以及确保数值积分的稳定性。此外,水动力导数的正确代入和单位转换也需要仔细处理。例如,给定的导数可能是无量纲的,需要转换为有量纲形式,涉及到船舶参数如长度、速度、密度等。最后,代码部分需要用Python实现,可能涉及解算微分方程组,绘制轨迹图,计算特征参数。需要测试代码的正确性,比如检查是否在恒定舵角下,船舶进入稳定的回转圈。</think>以下分步骤回答您的问题: 1. **船体参数及航速** ```python # 船体参数示例(VLCC油轮) L = 320.0 # 船长(m) B = 60.0 # 船宽(m) draft = 20.0 # 吃水(m) U = 7.72 # 航速(m/s) 15节转换 Cb = 0.85 # 方型系数 ``` 2. **坐标系与操纵运动方程** 采用右手坐标系: - X轴:指向船首 - Y轴:指向右舷 - Z轴:垂直向下 非线性三自由度方程: ``` m(u̇ - vr) = X m(v̇ + ur) = Y Izzṙ = N ``` 其中: - X = X_H + X_P + X_R - Y = Y_H + Y_R - N = N_H + N_R 3. **K-T参数计算** 假设给定水动力导数: ``` Yv = -1.2e6 # 横荡导数 Yr = 2.4e5 # 艏摇耦合导数 Nv = -3.8e5 # 横荡力矩导数 Nr = -2.1e7 # 艏摇阻尼导数 Nδ = 8.2e5 # 舵力矩导数 ``` K-T参数计算: ``` K = Nδ / (Nr - Yv*U/L) T = (Iz - Nr) / (Yv*Nr - Nv*Yr) ``` 4. **离散方法择(欧拉法)** ```python def euler_integration(state, dt, func): new_state = state + func(state) * dt return new_state ``` 5. **Python仿真程序** ```python import numpy as np import matplotlib.pyplot as plt class ShipModel: def __init__(self): self.m = 3.2e8 # 质量(kg) self.Iz = 1.2e10 # 转动惯量 self.L = 320.0 self.U = 7.72 # 水动力导数 self.Yv = -1.2e6 self.Yr = 2.4e5 self.Nv = -3.8e5 self.Nr = -2.1e7 self.Nδ = 8.2e5 def dynamics(self, state, δ): u, v, r, ψ, x, y = state Y = self.Yv*v + self.Yr*r N = self.Nv*v + self.Nr*r + self.Nδ*δ v_dot = (Y - self.m*u*r)/self.m r_dot = N/self.Iz u_dot = 0 # 假设航速恒定 ψ_dot = r x_dot = u*np.cos(ψ) - v*np.sin(ψ) y_dot = u*np.sin(ψ) + v*np.cos(ψ) return np.array([u_dot, v_dot, r_dot, ψ_dot, x_dot, y_dot]) def simulate_turning(): model = ShipModel() dt = 1.0 # 时间步长(s) δ = np.radians(35) # 舵角35度 # 初始状态 [u, v, r, ψ, x, y] state = np.array([model.U, 0, 0, 0, 0, 0]) # 仿真记录 states = [state] for t in np.arange(0, 600, dt): deriv = model.dynamics(state, δ) state = state + deriv * dt states.append(state) return np.array(states) # 执行仿真并绘图 results = simulate_turning() plt.plot(results[:,4], results[:,5]) plt.xlabel('X Position (m)') plt.ylabel('Y Position (m)') plt.title('Turning Circle Simulation') plt.grid(True) plt.show() ``` 6. **回转运动仿真** 代码已实现35度舵角回转仿真,舵速率通过线性插值实现: ```python def δ_command(t): max_rate = 5.0 # 5度/秒 target_δ = 35.0 current_δ = min(target_δ, max_rate * t) return np.radians(current_δ) ``` 7. **特征参数计算** ```python # 计算回转直径 y_pos = results[:,5] max_deviation = np.max(y_pos) tactical_diameter = 2 * max_deviation print(f"Tactical Diameter: {tactical_diameter:.1f} m") ``` 8. **IMO规范验证** IMO要求油轮战术直径应小于5倍船长: ``` if tactical_diameter < 5*L: print("满足IMO要求") else: print("不满足IMO要求") ``` 9. **操纵性改进** - 增大舵面积可提高K值 - 优化船体线型降低T值 - 添加舵球改善流动分离
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值