SP15637 GNYR04H - Mr Youngs Picture Permutations(洛谷)

该博客介绍了一种使用线性动态规划(DP)解决组合计数问题的方法。代码示例展示了如何处理五维数组,遍历并计算满足特定条件的组合总数。通过填充一个五维数组f,并初始化为0,博主逐步更新数组元素以计算最终结果。这个算法适用于处理有限范围内的组合计数问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://www.luogu.com.cn/problem/SP15637
算法:(线性DP);
代码:

#include<bits/stdc++.h>
using namespace std;
int t,n[10];
int main(){
    while(cin>>t){
        if(t==0){
            return 0;
        }
        memset(n,0,sizeof(n));
        for(int i=1;i<=k;i++){
            cin>>n[i];
        }
        unsigned long long f[31][16][11][9][7];
        memset(f,0,sizeof(f));
        f[0][0][0][0][0]=1;
        for(int i=0;i<=n[1];i++){
            for(int j=0;j<=n[2];j++){
                for(int k=0;k<=n[3];k++){
                    for(int l=0;l<=n[4];l++){
                        for(int m=0;m<=n[5];m++){
                            int point=f[i][j][k][l][m];                    
                            if(i<n[1]) f[i+1][j][k][l][m]+=point;
                            if(j<n[2]&&j<i) f[i][j+1][k][l][m]+=point;
                            if(k<n[3]&&k<j) f[i][j][k+1][l][m]+=point;
                            if(l<n[4]&&l<k) f[i][j][k][l+1][m]+=point;
                            if(m<n[5]&&m<l) f[i][j][k][l][m+1]+=point;
                    	}
                    }
                }
            }
        }
        cout<<f[n[1]][n[2]][n[3]][n[4]][n[5]]<<endl;
    }
    return 0;
}
<think>我们现在的目标是如何自动获取youngs_modulus模块输出的excel以及结果。根据之前的上下文,youngs_modulus模块中的calculate_youngs_modulus函数会返回一个包含所有结果的字典,其中包括应变、应力数组以及计算得到的参数。但是,如果用户希望将计算结果(包括原始数据和计算结果)保存到Excel,并且绘图脚本能够自动获取这个Excel文件,我们需要在youngs_modulus模块中添加保存Excel的功能,并返回该Excel文件的路径,然后在绘图脚本中读取这个Excel文件(可选,因为绘图所需数据已经通过字典传递,但保存Excel可以作为中间结果)。 然而,根据问题描述,用户希望自动获取youngs_modulus模块输出的Excel以及结果。这里有两种理解: 1. 用户希望youngs_modulus模块在计算过程中将结果保存为Excel文件,并将该文件路径返回,以便在绘图脚本中知道Excel文件的位置(可能用于其他用途,比如记录)。 2. 用户希望绘图脚本能够读取youngs_modulus模块生成的Excel文件(而不是直接使用返回的字典数据)来绘图。 但根据之前的代码,绘图脚本已经通过字典获取了所有需要的数据,并不需要再读取Excel。所以,如果用户希望有Excel输出,我们可以修改youngs_modulus模块,使其在计算完成后将结果(包括原始数据和计算结果)保存到Excel,并将该Excel路径返回。 因此,我们需要: 1. 在youngs_modulus模块的calculate_youngs_modulus函数中,添加保存Excel的步骤。 2. 在返回的字典中加入Excel文件路径(例如'result_excel_path')。 3. 在绘图脚本中,可以选择使用这个Excel文件路径(虽然绘图不需要,但用户可能需要知道Excel文件保存的位置)。 修改youngs_modulus模块的示例: 在youngs_modulus.py中: - 计算完成后,创建一个DataFrame,包含原始应变、应力数据,还可以添加一列标记弹性结束点、屈服点等(可选)。 - 将计算结果(如杨氏模量、屈服点等)写入到另一个工作表或同一工作表的特定位置。 由于问题描述中并没有要求绘图脚本从Excel中读取数据来绘图(而是直接使用返回的数组),所以我们在youngs_modulus模块中保存Excel主要是为了记录结果。 下面给出youngs_modulus模块中保存Excel的示例代码,并返回Excel文件路径。 注意:绘图脚本中已经通过返回的字典获取了绘图所需的数据,因此不需要再从Excel读取。保存Excel只是为了保留中间结果。 修改后的youngs_modulus.py示例: ```python import numpy as np import os import pandas as pd from scipy import stats import openpyxl # 用于写入多个工作表 def calculate_youngs_modulus(excel_path): """ 计算杨氏模量和屈服点的函数,并将结果保存到Excel 返回绘图所需的所有参数和结果Excel文件路径 """ # 从Excel文件读取数据 try: df = pd.read_excel(excel_path) strain = df['Strain'].values stress = df['Stress'].values except Exception as e: print(f"读取Excel文件错误: {e}") return None # 计算参数(简化示例) # 假设弹性阶段为前5个点 slope, intercept, _, _, _ = stats.linregress(strain[:5], stress[:5]) E = slope # 杨氏模量 elastic_end_point = (strain[4], stress[4]) # 弹性阶段结束点 # 这里假设屈服点是应力-应变曲线与偏移直线的第一个交点,简化处理 offset = 0.002 # 实际计算屈服点的方法可能更复杂,这里用示例数据 intersection_points = [(strain[8], stress[8])] # 屈服点 best_idx = 4 # 弹性阶段结束点索引 # 创建输出目录 output_dir = os.path.join(os.path.dirname(excel_path), "output_charts") os.makedirs(output_dir, exist_ok=True) # 保存结果到Excel result_excel_path = os.path.join(output_dir, "calculation_results.xlsx") # 创建Excel写入器 with pd.ExcelWriter(result_excel_path, engine='openpyxl') as writer: # 写入原始数据 df.to_excel(writer, sheet_name='原始数据', index=False) # 创建结果数据框 results_df = pd.DataFrame({ '参数': ['杨氏模量 (MPa)', '拟合截距 (MPa)', '弹性结束点应变', '弹性结束点应力 (MPa)', '屈服点应变', '屈服点应力 (MPa)', '偏移量'], '值': [E, intercept, elastic_end_point[0], elastic_end_point[1], intersection_points[0][0], intersection_points[0][1], offset] }) results_df.to_excel(writer, sheet_name='计算结果', index=False) # 如果需要,可以写入更多详细信息 print(f"计算结果已保存至: {result_excel_path}") # 返回所有计算结果 return { 'strain': strain, 'stress': stress, 'E': E, 'intercept': intercept, 'elastic_end_point': elastic_end_point, 'intersection_points': intersection_points, 'offset': offset, 'best_idx': best_idx, 'output_dir': output_dir, 'result_excel_path': result_excel_path # 新增Excel文件路径 } ``` 在绘图脚本中,我们可以通过返回的字典获取这个Excel文件路径,并输出给用户: ```python if __name__ == '__main__': excel_path = input("请输入Excel文件完整路径: ") results = ym.calculate_youngs_modulus(excel_path) if results is None: print("计算失败,请检查输入文件。") exit(1) # 提取结果 strain = results['strain'] stress = results['stress'] E = results['E'] intercept = results['intercept'] elastic_end_point = results['elastic_end_point'] intersection_points = results['intersection_points'] offset = results['offset'] best_idx = results['best_idx'] output_dir = results['output_dir'] result_excel_path = results['result_excel_path'] # 获取Excel文件路径 # 绘图 chart_path = youngs_plot( strain, stress, E, intercept, elastic_end_point, intersection_points, offset, best_idx, output_dir ) print(f"图表已成功生成: {chart_path}") print(f"计算结果Excel文件: {result_excel_path}") ``` 这样,用户就可以在运行脚本后得到两个输出:图表和包含计算结果的Excel文件。 注意:以上代码中计算屈服点的方法是简化的,实际应用中需要根据具体方法计算。 因此,我们通过修改youngs_modulus模块,使其在计算过程中保存Excel结果文件,并将该文件路径返回,从而实现了自动获取Excel输出。 如果问题是如何在绘图脚本中读取youngs_modulus模块输出的Excel文件(而不是使用返回的字典数据)来绘图,那么这种做法是不必要的,因为我们已经通过字典传递了所有数据。但为了满足用户要求,我们提供了保存Excel并返回路径的功能。 现在,用户可以在运行脚本后得到计算结果Excel文件,其中包含原始数据和计算结果。 总结:在youngs_modulus模块中添加保存Excel的步骤,并在返回字典中包含该Excel文件的路径,然后在主脚本中输出该路径。 §§相关问题§§ 1. 如果计算结果Excel文件需要包含多个屈服点的详细信息,应如何修改youngs_modulus模块中的结果保存部分? 2. 如何确保在写入多个工作表时不会覆盖已有的工作表(例如,如果多次运行)? 3. 除了Excel,如何支持将计算结果保存为CSV或JSON格式? 4. 如果原始数据量很大,如何避免在保存Excel时占用过多内存和时间? 5. 如何将绘制的图表嵌入到生成的Excel文件中,而不是单独保存为图片?</think>要自动获取 `youngs_modulus` 模块输出的 Excel 文件路径和计算结果,我们可以修改代码,使模块返回计算结果和输出文件路径。以下是完整的解决方案: ### 修改后的绘图脚本 (`youngs_plot.py`) ```python import matplotlib.pyplot as plt import numpy as np import os import matplotlib as mpl import youngs_modulus as ym # 导入杨氏模量计算模块 def youngs_plot(strain, stress, E, intercept, elastic_end_point, intersection_points, offset, best_idx, output_dir): """ 绘制杨氏模量拟合和屈服点确定图表 参数: strain: 真实应变数组 stress: 真实应力数组 E: 杨氏模量 (MPa) intercept: 线性拟合截距 elastic_end_point: 弹性阶段结束点 (strain, stress) intersection_points: 交点列表 [(应变, 应力)] offset: 屈服强度延伸率 best_idx: 弹性阶段结束点索引 output_dir: 图表保存目录 """ # 1. 重建平移直线 offset_line = lambda x: E * (x - offset) + intercept plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'WenQuanYi Micro Hei'] # 中文字体列表 plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题 # ============================ # 弹性阶段拟合与屈服点确定图 # ============================ plt.figure(figsize=(10, 6)) # 绘制原始数据 - 实线 plt.plot(strain, stress, 'b-', label='原始数据', alpha=0.7, linewidth=2) # 绘制弹性阶段拟合直线 - 虚线 elastic_fit_x = np.linspace(0, elastic_end_point[0], 50) elastic_fit_y = E * elastic_fit_x + intercept plt.plot(elastic_fit_x, elastic_fit_y, 'm--', linewidth=2.5, label=f'弹性阶段拟合 (E={E / 1000:.1f} GPa)') # 绘制平移直线 - 虚线 offset_fit_x = np.linspace(offset, max(strain), 50) offset_fit_y = offset_line(offset_fit_x) plt.plot(offset_fit_x, offset_fit_y, 'g--', linewidth=2, label=f'偏移{offset * 100:.1f}%直线') # 标记弹性阶段结束点 plt.plot(elastic_end_point[0], elastic_end_point[1], 'co', markersize=8, label=f'弹性结束点 (ε={elastic_end_point[0]:.4f}, σ={elastic_end_point[1]:.1f} MPa)') # 标记交点(屈服点) if intersection_points: for i, (x, y) in enumerate(intersection_points): plt.plot(x, y, 'r*', markersize=12, label=f'屈服点{i + 1} (ε={x:.4f}, σ={y:.1f} MPa)') # 设置y轴范围 y_max = max(stress) * 1.15 plt.ylim(0, y_max) # 添加网格和标签 plt.title('弹性阶段拟合与屈服点确定', fontsize=14) plt.xlabel('真实应变 (ε)', fontsize=12) plt.ylabel('真实应力 (σ, MPa)', fontsize=12) plt.legend(loc='best', fontsize=9) plt.grid(True, linestyle='--', alpha=0.7) plt.tight_layout() # 保存图表 chart_path = os.path.join(output_dir, 'elastic_fit.png') plt.savefig(chart_path, dpi=300) print(f"\n弹性阶段拟合图表已保存为 '{chart_path}'") plt.close() return chart_path if __name__ == '__main__': # 从用户输入或固定路径获取Excel文件路径 excel_path = input("请输入Excel文件完整路径: ") # 用户输入方式 # 或者使用固定路径: excel_path = "C:/data/material_test.xlsx" # 从youngs_modulus模块获取计算结果 results = ym.calculate_youngs_modulus(excel_path) if results is None: print("计算失败,请检查输入文件和错误信息") exit(1) # 提取计算结果作为绘图参数 strain = results['strain'] stress = results['stress'] E = results['E'] intercept = results['intercept'] elastic_end_point = results['elastic_end_point'] intersection_points = results['intersection_points'] offset = results['offset'] best_idx = results['best_idx'] output_dir = results['output_dir'] result_excel_path = results['result_excel_path'] # 获取结果Excel路径 # 调用绘图函数 chart_path = youngs_plot( strain, stress, E, intercept, elastic_end_point, intersection_points, offset, best_idx, output_dir ) # 输出所有结果路径 print("\n===== 计算结果和输出文件 =====") print(f"1. 输入Excel文件: {excel_path}") print(f"2. 计算结果Excel文件: {result_excel_path}") print(f"3. 图表文件: {chart_path}") print("============================") # 可选:打开结果目录 if os.name == 'nt': # Windows系统 os.startfile(output_dir) elif os.name == 'posix': # macOS或Linux os.system(f'open "{output_dir}"' if sys.platform == 'darwin' else f'xdg-open "{output_dir}"') ``` ### 修改后的 `youngs_modulus.py` 模块 ```python import numpy as np import os import pandas as pd from scipy import stats import matplotlib.pyplot as plt def calculate_youngs_modulus(excel_path): """ 计算杨氏模量和屈服点的函数,并保存结果到Excel 参数: excel_path: Excel文件路径 返回: dict: 包含所有计算结果和文件路径的字典 """ try: # 1. 读取Excel文件 df = pd.read_excel(excel_path) # 自动检测列名 strain_col = next((col for col in df.columns if 'strain' in col.lower()), None) stress_col = next((col for col in df.columns if 'stress' in col.lower()), None) if not strain_col or not stress_col: raise ValueError("未找到应变(strain)或应力(stress)列") strain = df[strain_col].values stress = df[stress_col].values # 2. 计算杨氏模量(使用前5%的数据点作为弹性阶段) elastic_ratio = 0.05 # 使用前5%的数据点 n_elastic = max(5, int(len(strain) * elastic_ratio)) slope, intercept, _, _, _ = stats.linregress(strain[:n_elastic], stress[:n_elastic]) E = slope # 杨氏模量 elastic_end_point = (strain[n_elastic-1], stress[n_elastic-1]) best_idx = n_elastic - 1 # 3. 计算屈服点(0.2%偏移法) offset = 0.002 # 0.2%偏移 # 创建偏移直线函数 offset_line = lambda x: E * (x - offset) + intercept # 找到偏移直线与应力-应变曲线的交点 intersection_points = [] for i in range(n_elastic, len(strain)): if stress[i] >= offset_line(strain[i]): intersection_points.append((strain[i], stress[i])) break # 只取第一个交点 # 4. 创建输出目录 base_name = os.path.splitext(os.path.basename(excel_path))[0] output_dir = os.path.join(os.path.dirname(excel_path), f"{base_name}_results") os.makedirs(output_dir, exist_ok=True) # 5. 保存计算结果到新Excel文件 result_excel_path = os.path.join(output_dir, f"{base_name}_results.xlsx") with pd.ExcelWriter(result_excel_path) as writer: # 保存原始数据 df.to_excel(writer, sheet_name='原始数据', index=False) # 创建计算结果表 results_df = pd.DataFrame({ '参数': [ '杨氏模量 (MPa)', '杨氏模量 (GPa)', '拟合截距 (MPa)', '弹性结束点应变', '弹性结束点应力 (MPa)', '屈服点应变', '屈服点应力 (MPa)', '偏移量' ], '值': [ E, E / 1000, intercept, elastic_end_point[0], elastic_end_point[1], intersection_points[0][0] if intersection_points else None, intersection_points[0][1] if intersection_points else None, offset ] }) results_df.to_excel(writer, sheet_name='计算结果', index=False) # 添加弹性阶段数据标记 df_elastic = df.copy() df_elastic['阶段'] = '塑性' df_elastic.loc[:best_idx, '阶段'] = '弹性' df_elastic.to_excel(writer, sheet_name='标记数据', index=False) print(f"计算结果已保存至: {result_excel_path}") # 6. 返回所有结果 return { 'strain': strain, 'stress': stress, 'E': E, 'intercept': intercept, 'elastic_end_point': elastic_end_point, 'intersection_points': intersection_points, 'offset': offset, 'best_idx': best_idx, 'output_dir': output_dir, 'result_excel_path': result_excel_path } except Exception as e: print(f"处理过程中发生错误: {str(e)}") import traceback traceback.print_exc() return None ``` ### 关键功能说明: 1. **自动获取结果Excel文件**: ```python # 在youngs_modulus.py中 result_excel_path = os.path.join(output_dir, f"{base_name}_results.xlsx") # ... return { # ... 其他结果 ... 'result_excel_path': result_excel_path } # 在主脚本中 result_excel_path = results['result_excel_path'] print(f"计算结果Excel文件: {result_excel_path}") ``` 2. **自动检测列名**: ```python # 自动检测应变和应力列 strain_col = next((col for col in df.columns if 'strain' in col.lower()), None) stress_col = next((col for col in df.columns if 'stress' in col.lower()), None) ``` 3. **弹性阶段自动检测**: ```python # 使用前5%的数据点作为弹性阶段 elastic_ratio = 0.05 n_elastic = max(5, int(len(strain) * elastic_ratio)) ``` 4. **结果Excel文件包含**: - 原始数据表 - 计算结果表(杨氏模量、屈服点等) - 标记数据表(弹性/塑性阶段标记) 5. **结果输出**: ```python print("\n===== 计算结果和输出文件 =====") print(f"1. 输入Excel文件: {excel_path}") print(f"2. 计算结果Excel文件: {result_excel_path}") print(f"3. 图表文件: {chart_path}") ``` 6. **自动打开结果目录**: ```python # 根据操作系统自动打开结果目录 if os.name == 'nt': # Windows os.startfile(output_dir) elif os.name == 'posix': # macOS/Linux os.system(f'open "{output_dir}"' if sys.platform == 'darwin' else f'xdg-open "{output_dir}"') ``` ### 使用流程: 1. 运行主脚本 `youngs_plot.py` 2. 输入原始数据Excel文件路径 3. 脚本将: - 自动读取Excel文件 - 计算杨氏模量和屈服点 - 在原始文件所在目录创建结果文件夹 - 保存计算结果到新的Excel文件 - 生成图表 - 输出所有文件路径 - 自动打开结果目录 ### 结果Excel文件示例: **原始数据表**: | Strain | Stress (MPa) | |------------|--------------| | 0.0001 | 20 | | 0.0002 | 40 | | ... | ... | **计算结果表**: | 参数 | 值 | |--------------------|--------------| | 杨氏模量 (MPa) | 200000 | | 杨氏模量 (GPa) | 200.0 | | 拟合截距 (MPa) | 5.0 | | 弹性结束点应变 | 0.0005 | | 弹性结束点应力 (MPa)| 100.0 | | 屈服点应变 | 0.0025 | | 屈服点应力 (MPa) | 450.0 | | 偏移量 | 0.002 | **标记数据表**: | Strain | Stress (MPa) | 阶段 | |------------|--------------|-------| | 0.0001 | 20 | 弹性 | | 0.0002 | 40 | 弹性 | | ... | ... | ... | | 0.0025 | 450 | 塑性 | 这样,您就可以自动获取 `youngs_modulus` 模块计算的结果和生成的Excel文件路径,实现完整的材料性能分析流程。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值