定量计算洛谷用户的刷题水平(需要一定数学)
数学基础:1. 正态分布
2. 线性回归法
思路很简单,但数学实现很逆天
输入格式
第一行一个整数 N ,表示洛谷的题目种类数。(2<N<100)
第二行 N 个整数 a1 , a2 , ... , aN ,表示用户刷的题目中各个难度层次的刷题量。
其中某一难度层次 i 在坐标轴中的横坐标为 x=100i 。(为了避免浮点精度过低)
输出格式
请对这 N 个数据进行线性回归,拟合出一条正态分布曲线,曲线的顶点即为该用户的刷题水平。输出顶点的横坐标。
若数据分布明显不符合正态分布(X*,Y* 的相关系数 < 0.2)输出一行"逆天"。
具体题目还在配置中,题解也没写完,各位可以先把实现代码发出来。 首先需要明确的是,这道题需要用到的是正态分布曲线的拟合和线性回归法,需要具备一定的数学基础。
接下来,我们来分析一下思路。
由于该用户刷题量的分布情况是不确定的,我们需要对其进行拟合,考虑使用正态分布曲线来拟合。正态分布曲线是一个钟形曲线,可以用公式 y = 1/(σ√(2π)) * e^(-(x-μ)^2/(2σ^2)) 来表示。其中,μ是分布的均值,σ是分布的标准差。
然后,我们需要对该用户的刷题水平进行评估,考虑使用线性回归法。线性回归法是一种用于确定两种变量之间关系的方法,可以用一条直线来拟合两个变量之间的关系。在本题中,我们需要将正态分布曲线的拟合结果进行线性回归,得到该用户刷题水平的评估结果。
具体实现细节可以参考以下代码:
import numpy as np
from scipy.optimize import curve_fit
# 定义正态分布函数
def normal_distribution(x, mu, sigma):
return 1/(sigma*np.sqrt(2*np.pi))*np.exp(-(x-mu)**2/(2*sigma**2))
# 定义线性函数
def linear_func(x, a, b):
return a*x + b
# 读入数据
n = int(input())
x_data = np.array()
y_data = np.array(list(map(int, input().split())))
# 拟合正态分布曲线
popt, _ = curve_fit(normal_distribution, x_data, y_data)
mu, sigma = popt
# 计算相关系数
r = np.corrcoef(x_data, y_data)
# 判断是否符合正态分布
if abs(r) < 0.2:
print("逆天")
else:
# 拟合线性回归
popt, _ = curve_fit(linear_func, x_data, normal_distribution(x_data, mu, sigma))
a, b = popt
# 计算顶点横坐标
vertex_x = -b/a
print(int(vertex_x))
注意,由于正态分布曲线的拟合和线性回归法都需要使用最小二乘法,因此需要使用SciPy库中的curve_fit函数来进行拟合。同时,由于题目中要求输出整数,因此需要使用int函数将结果转换为整数。 要实现洛谷用户的刷题水平的定量计算,可以使用线性回归和正态分布拟合的方法。以下是一个可能的实现代码:
import numpy as np
from scipy.stats import norm, pearsonr
# 读取输入数据
N = int(input())
a = list(map(int, input().split()))
# 计算横坐标和纵坐标
x = np.array()
y = np.array(a)
# 计算相关系数
corr = np.abs(pearsonr(x, y))
# 判断数据是否符合正态分布
if corr < 0.2:
print("逆天")
else:
# 线性回归拟合
slope, intercept = np.polyfit(x, y, 1)
# 求解曲线的顶点(极值点)
vertex_x = -intercept / (2 * slope)
print(vertex_x)
这段代码首先读取输入的数据,然后使用 numpy 和 scipy.stats 库进行数值计算和统计分析。通过线性回归拟合数据,求解拟合曲线的顶点即为刷题水平。如果数据相关系数小于0.2,则输出"逆天"表示数据分布明显不符合正态分布。否则,输出拟合曲线的顶点横坐标。
请注意,此代码仅给出了基本实现思路,具体的题目配置和题解计算需要根据实际情况进行补充。
如果问题已经解决,请设置最佳答案 isdkz 发表于 2023-9-10 19:53
首先需要明确的是,这道题需要用到的是正态分布曲线的拟合和线性回归法,需要具备一定的数学基础。
接 ...
忘了还有ChatGPT这茬{:10_266:} 数学实现:
要解决这个问题,我们可以使用最小二乘法来进行线性回归。首先,我们需要计算用户刷题量数据的均值和标准差,以确定正态分布曲线的参数。
假设刷题量数据为 x,题目难度层次数据为 y,分别表示题目难度层次的横坐标和用户刷题量。我们需要拟合的直线方程为 y = a*x + b,其中 a 是斜率,b 是截距。
我们可以使用下面的公式计算 a 和 b 的估计值:
a = (sum(x*y) - N*mean(x)*mean(y)) / (sum(x*x) - N*mean(x)*mean(x))
b = mean(y) - a*mean(x)
接下来,我们可以根据正态分布曲线的公式 f(x) = A * exp(-((x-mu)^2)/(2*sigma^2)),对于每个难度层次的横坐标 xi,计算相应的 yi(即题目数量),其中 A 是高度,mu 是曲线的顶点横坐标,sigma 是标准差。
接下来,我们可以使用最小二乘法来计算 A、mu 和 sigma 的估计值。
若相关系数 r 的绝对值小于 0.2,则输出 "逆天"。
下面是实现代码:
#include <iostream>
#include <vector>
#include <cmath>
struct Point {
double x;
double y;
};
double calculateMean(std::vector<double>& data) {
double sum = 0.0;
for (double value : data) {
sum += value;
}
return sum / data.size();
}
double calculateStandardDeviation(std::vector<double>& data) {
double mean = calculateMean(data);
double variance = 0.0;
for (double value : data) {
variance += (value - mean) * (value - mean);
}
variance /= data.size();
return std::sqrt(variance);
}
double calculateCorrelationCoefficient(std::vector<Point>& points) {
double sumX = 0.0;
double sumY = 0.0;
double sumXY = 0.0;
double sumX2 = 0.0;
double sumY2 = 0.0;
for (const Point& point : points) {
sumX += point.x;
sumY += point.y;
sumXY += point.x * point.y;
sumX2 += point.x * point.x;
sumY2 += point.y * point.y;
}
int n = points.size();
double numerator = n * sumXY - sumX * sumY;
double denominator = std::sqrt((n * sumX2 - sumX * sumX) * (n * sumY2 - sumY * sumY));
return numerator / denominator;
}
int main() {
int N;
std::cin >> N;
std::vector<double> xValues(N);// 难度层次的横坐标
std::vector<double> yValues(N);// 用户刷题量
for (int i = 0; i < N; ++i) {
std::cin >> yValues;
xValues = 100 * (i + 1);
}
// 计算线性回归
double meanX = calculateMean(xValues);
double meanY = calculateMean(yValues);
double sumXY = 0.0;
double sumX2 = 0.0;
for (int i = 0; i < N; ++i) {
sumXY += xValues * yValues;
sumX2 += xValues * xValues;
}
double a = (sumXY - N * meanX * meanY) / (sumX2 - N * meanX * meanX);
double b = meanY - a * meanX;
// 计算正态分布参数
std::vector<Point> points(N);
for (int i = 0; i < N; ++i) {
points.x = xValues;
points.y = yValues;
}
double correlationCoefficient = std::abs(calculateCorrelationCoefficient(points));
if (correlationCoefficient < 0.2) {
std::cout << "逆天" << std::endl;
} else {
double sigma = calculateStandardDeviation(yValues);
double A = 1.0 / (sigma * std::sqrt(2 * M_PI));
double mu = (b - meanX) / a;// 曲线顶点的横坐标
std::cout << mu << std::endl;
}
return 0;
}
上述代码通过输入方式获取题目种类数和用户刷题数量,并按照给定的格式进行了实现。通过线性回归和正态分布的计算,输出了用户的刷题水平。
请根据实际需求自行调整代码并进行测试。如果有任何问题,请随时提问。
球一个最佳答案谢谢啦!这对我非常重要!{:10_254:}{:10_254:}{:10_254:}
镍麻麻的。GPT直接给题解了是吧。不过大概率是错的 不会 虽然不会,但是先白嫖{:10_256:} 什么地狱难度 {:10_269:}看不懂 ? 什么意思 看不懂 {:10_254:}! @zhangjinxuan 完全看不懂{:10_319:} {:5_109:} 学习 ? 看不懂{:10_269:},但是先领币{:10_256:}