额外减小 发表于 2023-9-10 19:53:16

定量计算洛谷用户的刷题水平(需要一定数学)

数学基础:

1. 正态分布
2. 线性回归法

思路很简单,但数学实现很逆天

输入格式

第一行一个整数 N ,表示洛谷的题目种类数。(2<N<100)
第二行 N 个整数 a1 , a2 , ... , aN ,表示用户刷的题目中各个难度层次的刷题量。
其中某一难度层次 i 在坐标轴中的横坐标为 x=100i 。(为了避免浮点精度过低)

输出格式

请对这 N 个数据进行线性回归,拟合出一条正态分布曲线,曲线的顶点即为该用户的刷题水平。输出顶点的横坐标。

若数据分布明显不符合正态分布(X*,Y* 的相关系数 < 0.2)输出一行"逆天"。

具体题目还在配置中,题解也没写完,各位可以先把实现代码发出来。

isdkz 发表于 2023-9-10 19:53:29

首先需要明确的是,这道题需要用到的是正态分布曲线的拟合和线性回归法,需要具备一定的数学基础。



接下来,我们来分析一下思路。



由于该用户刷题量的分布情况是不确定的,我们需要对其进行拟合,考虑使用正态分布曲线来拟合。正态分布曲线是一个钟形曲线,可以用公式 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函数将结果转换为整数。

陶远航 发表于 2023-9-10 19:53:40

要实现洛谷用户的刷题水平的定量计算,可以使用线性回归和正态分布拟合的方法。以下是一个可能的实现代码:

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,则输出"逆天"表示数据分布明显不符合正态分布。否则,输出拟合曲线的顶点横坐标。

请注意,此代码仅给出了基本实现思路,具体的题目配置和题解计算需要根据实际情况进行补充。
如果问题已经解决,请设置最佳答案

额外减小 发表于 2023-9-10 19:54:03

isdkz 发表于 2023-9-10 19:53
首先需要明确的是,这道题需要用到的是正态分布曲线的拟合和线性回归法,需要具备一定的数学基础。



接 ...

忘了还有ChatGPT这茬{:10_266:}

Mike_python小 发表于 2023-9-10 19:54:09

数学实现:

要解决这个问题,我们可以使用最小二乘法来进行线性回归。首先,我们需要计算用户刷题量数据的均值和标准差,以确定正态分布曲线的参数。

假设刷题量数据为 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:}

额外减小 发表于 2023-9-10 19:55:28

镍麻麻的。GPT直接给题解了是吧。不过大概率是错的

liuhongrun2022 发表于 2023-9-10 19:55:55

不会

歌者文明清理员 发表于 2023-9-10 19:57:21

虽然不会,但是先白嫖{:10_256:}

sfqxx 发表于 2023-9-10 19:58:58

什么地狱难度

Wei-Yuanzhe 发表于 2023-9-10 20:12:59

{:10_269:}看不懂

琅琊王朝 发表于 2023-9-10 20:46:24

?

琅琊王朝 发表于 2023-9-10 20:47:25

什么意思

kerln888 发表于 2023-9-11 08:54:49

看不懂

kaneki.ken 发表于 2023-9-11 17:09:33

{:10_254:}!

歌者文明清理员 发表于 2023-9-11 19:05:51

@zhangjinxuan

wngyoucai 发表于 2023-9-11 22:20:39

完全看不懂{:10_319:}

16beat 发表于 2023-9-12 09:52:43

{:5_109:}

JINH 发表于 2023-9-14 14:23:39

学习

琅琊王朝 发表于 2023-9-14 21:06:51

zsy0226 发表于 2023-9-16 13:14:28

看不懂{:10_269:},但是先领币{:10_256:}
页: [1] 2 3
查看完整版本: 定量计算洛谷用户的刷题水平(需要一定数学)