首页 > 试题广场 >

封闭图形的面积(技术研究卷)

[编程题]封闭图形的面积(技术研究卷)
  • 热度指数:2213 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 128M,其他语言256M
  • 算法知识视频讲解

求抛物线 = 与直线 = + 所围成的封闭图形面积.若图形不存在,则输出



输入描述:

第一行输入一个正整数T.表示测试数据组数.

接下来每行输入三个整数A , B和 C.

1<=T<=1000
1<=A,B<=100

-100<=C<=100




输出描述:
每组测试数据输出一个答案.在<1e-4范围内都视为正确输出.
示例1

输入

1
1 1 -6

输出

31.2481110540
var T = parseInt(readline())
for(var i =0;i<T;i++){
    var lines = readline().split(" ")
    var A = parseInt(lines[0])
    var B = parseInt(lines[1])
    var C = parseInt(lines[2])
    var a = B*B
    var b = 2*B*C-2*A
    var c = C*C
    var dt = b*b-4*a*c
    if(dt<=0){
        var zero = 0
        console.log(zero.toFixed(10))
    }else{
        var x1 = (-b+Math.sqrt(dt))/(2*a)
        var x2 = (-b-Math.sqrt(dt))/(2*a)
        var y1 = B*x1+C
        var y2 = B*x2+C
        if(y1<y2){
            var temp = y2
            y2=y1
            y1=temp
        }
        var result = ((y1*y1)/(2*B)-(y2*y2)/(2*B))-(C*y1/B-C*y2/B)-((y1*y1*y1)/(6*A)-(y2*y2*y2)/(6*A))
        console.log(result.toFixed(10))
    }
}

发表于 2021-08-23 20:56:16 回复(0)
首先解二次方程求出两个图形的交点,若交点数小于2则面积为0
假设我们求得的两个交点的y坐标分别为y1,y2.(y1>y2)
那么相交图形的面积就是两个函数在区间[y2,y1]上的积分之差,即
解这个积分方程即可
#include<bits/stdc++.h>
using namespace std;
const int nn =5100;
const int inff = 0x3fffffff;
const double eps = 1e-8;
typedef long long LL;
const double pi = acos(-1.0);
const LL mod = 1000000007;
int compare(double x)
{
    if(abs(x)<eps)
        return 0;
    if(x>0)
        return 1;
    return -1;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int A,B,C;
        cin>>A>>B>>C;
        double a,b,c;
        a=B*B;
        b=2*B*C-2*A;
        c=C*C;
        double dt=b*b-4*a*c;
        if(compare(dt)<=0)
            cout<<0<<endl;
        else {
            double x1=(-b+sqrt(dt))/(2*a);
            double x2=(-b-sqrt(dt))/(2*a);
            double y1=B*x1+C;
            double y2=B*x2+C;
            if(y1<y2)
                swap(y1,y2);
            double ans=((y1*y1)/(2*B)-(y2*y2)/(2*B))-(C*y1/B-C*y2/B)-((y1*y1*y1)/(6*A)-(y2*y2*y2)/(6*A));
            printf("%.6lf\n",ans);
        }
    }
    return 0;
}


发表于 2021-06-22 11:33:36 回复(0)
先根据求根公式求出抛物线和直线的纵坐标交点,ylb=(A-sqrt(A2-2ABC))/B,yub=(A+sqrt(A2-2ABC))/B
1.当A2-2ABC<0时,面积不存在
2.当A2-2ABC>=0时根据牛顿莱布尼兹公式,面积为
-yub3/6A+yub2/2B - Cyub/B - (-ylb3/6A+ylb2/2B - Cylb/B)
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    private static double A = 0;
    private static double B = 0;
    private static double C = 0;
    
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int T = Integer.parseInt(br.readLine());
        while(T -- > 0){
            String[] params = br.readLine().split(" ");
            A = Double.parseDouble(params[0]);
            B = Double.parseDouble(params[1]);
            C = Double.parseDouble(params[2]);
            if(A*A - 2*A*B*C < 0){
                System.out.println(0);
            }else{
                double lb = (A - Math.sqrt(A*A - 2*A*B*C)) / B;
                double ub = (A + Math.sqrt(A*A - 2*A*B*C)) / B;
                System.out.println(f(ub) - f(lb));
            }
        }
    }
    
    private static double f(double y) {
        return -y*y*y / (6*A) + y*y /(2*B) - C*y/B;
    }
}

编辑于 2021-07-22 14:58:18 回复(0)
import math

samples_num = int(input())  # 测试的样例数

list_A_B_C = []
for i in range(samples_num):
    list_A_B_C.append(input().split(" "))

def f(y):
    return -y * y * y / (6 * A) + y * y / (2 * B) - C * y / B

for A_B_C in list_A_B_C:
    A = int(A_B_C[0])
    B = int(A_B_C[1])
    C = int(A_B_C[-1])
    if A * A - 2 * A * B * C < 0:
        print(0)
    else:
        lb = (A - math.sqrt(A * A - 2 * A * B * C)) / B
        ub = (A + math.sqrt(A * A - 2 * A * B * C)) / B

        print(f(ub)- f(lb))

发表于 2021-08-21 15:25:48 回复(0)
怎么卡辛普森积分的?
发表于 2023-08-26 18:49:55 回复(0)
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int T = sc.nextInt(); // 测试数据组数

        while (T-- > 0) {
            int A = sc.nextInt(); // 抛物线参数
            int B = sc.nextInt(); // 直线斜率
            int C = sc.nextInt(); // 直线截距

            // 解交点方程: y^2 = 2Ax 与 y = Bx + C
            // B^2 * x^2 + (2BC-2A)x + C^2 = 0
            double a = B * B;
            double b = 2 * B * C - 2 * A;
            double c = C * C;

            List<Double> xValues = solveQuadratic(a, b, c);

            // 判断交点数量
            if (xValues.size() < 2) {
                System.out.println("0");
                continue;
            }

            double x1 = xValues.get(0);
            double x2 = xValues.get(1);

            // 求y值
            double y1 = x1 * B + C;
            double y2 = x2 * B + C;

            // 计算封闭图形面积
            double area = (y1 * y1 - y2 * y2) / (2 * B) - C * (y1 - y2) / B - (y1 * y1 * y1 - y2 * y2 * y2) / (6 * A);
            System.out.printf("%.10f\n", area);
        }

        sc.close();
    }

    // 解二次方程: ax^2 + bx + c = 0
    public static List<Double> solveQuadratic(double a, double b, double c) {
        List<Double> roots = new ArrayList<>();
        double discriminant = b * b - 4 * a * c;
        if (discriminant > 0) {
            double root1 = (-b + Math.sqrt(discriminant)) / (2 * a);
            double root2 = (-b - Math.sqrt(discriminant)) / (2 * a);
            roots.add(root1);
            roots.add(root2);
        }
        return roots;
    }
}

发表于 2023-09-10 03:07:50 回复(0)
#微分法,可以用来求不好算积分的曲线,精度由dy控制
import math
while True:
    try:
        T=int(input())
        for _ in range(T):
            A,B,C=list(map(int,input().split()))
            
            a=B*B
            b=2*B*C-2*A
            c=C*C
            dt=b*b-4*a*c

            if dt<=0:
                print(0)
                
            else :
                x1=(-b-math.sqrt(dt))/(2*a)
                x2=(-b+math.sqrt(dt))/(2*a)
                y1=B*x1+C
                y2=B*x2+C
                
                # 微分法
                dy=0.01
                # y_list = [i*dy for i in range(math.floor(y1/dy),math.ceil(y2/dy))]
                def y_generator(y1,y2,dy):
                    for i in range(math.floor(y1/dy),math.ceil(y2/dy)):
                        yield i*dy 
                y_list = y_generator(y1,y2,dy)
                
                ans=0
                for y in y_list:
                    d = abs(((y-C)/B)-(y*y)/(2*A))
                    ans+=d
                print(ans*dy)
            
    except: break
        

发表于 2022-10-16 03:22:37 回复(0)
import sys
T = sys.stdin.readline()
T = int(T.strip())
for _ in range(T):
    line = sys.stdin.readline()
    A,B,C = line.strip().split()
    A = int(A)
    B = int(B)
    C = int(C)
    delta = 4*A*A - 8*A*B*C
    if delta <= 0:
        print(0)
    else:
        x0 = -C/B
        y1_plus_y2 = 2*A/B
        y1_mult_y2 = 2*A*C/B
        y1_minu_y2 = ((delta)**(0.5)) / B
        y3_plus = y1_plus_y2 * ((y1_plus_y2**2)-3*y1_mult_y2)
        y3_minu = y1_minu_y2 * ((y1_plus_y2**2) - y1_mult_y2)
        #res = y3_plus/(6*A) + x0*y1_minu_y2/2 - y3_minu/(4*A)
        res = (y1_plus_y2 - 2*C)*(y1_minu_y2)/(2*B) - y3_minu/(6*A)
        print(res)
发表于 2022-04-22 06:59:17 回复(0)
先判断两条线是否相交,再求出2个交点的y1和y2,在y1到y2的积分域对(直线-曲线)做积分。
#include <iostream>
#include <math.h>

int main(){
    float A,B,C,T;
    float min_y,max_y;
    std::cin>>T;
    for(int i=0;i<T;i++){
        std::cin>>A>>B>>C;
        float temp=A*A-2*A*B*C;
        if(temp<=0){
            std::cout<<0<<std::endl;
        }
        else{
            float y1=(A+sqrt(temp))/B;
            float y2=(A-sqrt(temp))/B;
            if(y1>y2){
                max_y=y1;
                min_y=y2;
            }
            else{
                max_y=y2;
                min_y=y1;
            }
            float result=((max_y*max_y)/(2*B)-(max_y*C)/B-(max_y*max_y*max_y)/(6*A))-((min_y*min_y)/(2*B)-(min_y*C)/B-(min_y*min_y*min_y)/(6*A));
            std::cout<<result<<std::endl;
        }       
    }
    
    return 0;
}

发表于 2022-04-21 19:49:46 回复(0)
#include <bits/stdc++.h>
 
using namespace std;
 
int main()
{
    int T;
    cin>>T;
    for(int i=0; i<T; i++){
        int A, B, C;
        cin>>A>>B>>C;
        if(B==0){
            cout<<0<<endl;%把只有一个交点的情况拿出来讨论。
        }
        else{
            double delta = 4* pow(A,2)-8*B*A*C;
            if(delta <= 0){
                cout<<0<<endl;%把没有交点与只有一个交点的讨论
            }
            else{
                double y1=(2*A+sqrt(delta))/(2*B);
                double y2=(2*A-sqrt(delta))/(2*B);
                double ans = (pow(y1,2)/(2*B)-C*y1/B)-(pow(y2,2)/(2*B)-C*y2/B)- pow(y1,3)/(6*A)+ pow(y2,3)/(6*A);%直接计算积分值
                cout<<ans<<endl;
            }
        }
    }
    return 0;
}

编辑于 2022-04-14 16:04:40 回复(0)
a= input('');
mat = zeros(a,3);
for i = 1:a
    mat(i,:)= str2num(input('','s'));
    jie = roots([1/(2*mat(i,1)), -1/mat(i,2),mat(i,3)/mat(i,2)]);
    if (jie(1)== jie(2)) || (isreal(jie)~=1)
        out = 0;
    else
        fun = @(x) x.^2/(2*mat(i,1))-x/mat(i,2)+mat(i,3)/mat(i,2);
        out = integral(fun,jie(1),jie(2));
end
format long
disp(out)
end
有没有大神看看为什么只通过9组 (matlab)


编辑于 2022-03-15 17:27:02 回复(0)
使用求根公式求出两个交点(无解就是输出0)
利用牛顿莱布尼兹公式求出封闭面积
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
//#define mod 998244353
#define mod 1000000007
#define ll long long
using namespace std;
const int N=1e6+5;
const double eps=1e-8;
int n,m,k;double a,b,c;
int check(double x){
    if(fabs(x)<eps)return 0;
    if(x>0)return 1;
    return -1;
}
double calc(double y){
    return y*y/b/2-y*c/b-y*y*y/a/6;
}
void solve(){
    cin>>a>>b>>c;
    double ca=a*a-2*a*b*c;
    if(ca<=0){
        cout<<0<<'\n';
        return ; 
    }
    double y1=(a+sqrt(ca))/b;
    double y2=(a-sqrt(ca))/b;
    cout<<calc(y1)-calc(y2)<<'\n';
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cout<<fixed<<setprecision(10);
    int t;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}


发表于 2022-01-07 19:49:14 回复(0)
生而为人,我很抱歉
发表于 2021-12-22 23:42:25 回复(0)
#include<iostream>
#include<math.h>

using namespace std;

int main(){
    int t; cin >> t;
    while (t--){
        int A, B, C; cin >> A >> B >> C;
        int a = B * B, b = 2 * B * C - 2*A, c = C * C;
        int delta = b * b - 4 * a * c;
        if (delta <= 0){
            cout << 0 << endl;
            continue;
        }
        double x1 = (-b + sqrt(delta)) / (2 * a);
        double x2 = (-b - sqrt(delta)) / (2 * a);
        double y1 = B * x1 + C;
        double y2 = B * x2 + C;
        if (y1 < y2) swap(y1, y2);
        double ans = ((y1 * y1) - (y2 * y2)) / (2 * B) -C*(y1/B-y2/B) - (y1 * y1 * y1 - y2 * y2 * y2) / (6 * A);
        printf("%.6lf\n", ans);
    }
}

发表于 2021-11-03 11:00:19 回复(0)
Python代码:
while True:
    try:
        T = int(input())
        ABC = []
        for i in range(T):
            ABC1 = list(map(int,input().split()))
            ABC.append(ABC1)
    except:
        break 
import math
def f(y):
    return -y*y*y / (6*A) + y*y / (2*B) - C*y / B 

for i in ABC:
    A, B, C = i[0], i[1], i[2]
    if (A*A - 2*A*B*C < 0):
        print(0)
    else:
        lb = (A - math.sqrt(A*A - 2*A*B*C)) / B
        ub = (A + math.sqrt(A*A - 2*A*B*C)) / B
        print(f(ub) - f(lb))


发表于 2021-10-29 20:19:02 回复(0)
#include <iostream>
#include <cmath>
using namespace std;
int main(){
    int T;
    cin>>T;
    while(T--){
        int A,B,C;cin>>A>>B>>C;
        if((A*A-2*A*B*C)<=0){
            cout<<0<<endl;
        }
        double y1 = (static_cast<double>(A)-sqrt(static_cast<double>(A*A-2*A*B*C)))/(static_cast<double>(B));
        double y2 = (static_cast<double>(A)+sqrt(static_cast<double>(A*A-2*A*B*C)))/(static_cast<double>(B));
        double res = (y1*y1*y1-y2*y2*y2)/(6*A)-(y1*y1-y2*y2)/(2*B)+(y1-y2)*C/B;
        printf("%lf\n",res);
    }
    return 0;
我就想知道我的错在哪一个用例都没过
发表于 2021-09-05 15:11:28 回复(0)

这个题目是个数学题,主要是求定积分,要先求出是否存在交点,然后再来求面积

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int times = sc.nextInt();
        sc.nextLine();
        while (times > 0) {
            int a = sc.nextInt();
            int b = sc.nextInt();
            int c = sc.nextInt();
            //将方程转换为y型,求出关于y的二次方程的跟的判别式
            double delta = 4*a*a-8*a*b*c;
            if(delta<=0){
                System.out.println(0);
            }else{
                //然后用求根公式得到两个焦点的y
                double y1 = (2*a+Math.sqrt(delta))/(2*b);
                double y2 = (2*a-Math.sqrt(delta))/(2*b);
                //最后直接用定积分得到的表达式来进行求值,直接用绝对值可以直接求出面积
                System.out.printf("%.10f\n",Math.abs(getAnswer(y1,a,b,c)-getAnswer(y2,a,b,c)));
            }
            times--;
        }
    }
    public  static double getAnswer(double x,int a,int b,int c){
        //这里是定积分的表达式
        return x*x*x/6/a-x*x/2/b + x*c/b;
    }
}

发表于 2021-09-03 15:23:51 回复(0)
double cond = Math.pow(B*C-A, 2) - Math.pow(B*C,2);
            if (cond <= 0) {
                System.out.println((double)0);
                continue;
            }else {
                double x1 = (2*(A-B*C)+Math.sqrt(cond)) / (2*Math.pow(B,2));
                double x2 = (2*(A-B*C)-Math.sqrt(cond)) / (2*Math.pow(B,2));
                double y1 = B*x1 + C;
                double y2 = B*x2 + C;
                double inte1 = (-Math.pow(y1,3)/(6*A))+(Math.pow(y1,2)/(2*B))-(C*y1/B);
                double inte2 = (-Math.pow(y2,3)/(6*A))+(Math.pow(y2,2)/(2*B))-(C*y2/B);
                System.out.println(Math.abs(inte1-inte2));
            }
看着好像对,但是输出结果就是不一样,麻了
发表于 2021-09-01 11:21:44 回复(1)
这题考高数
发表于 2021-08-20 17:24:29 回复(0)
#include<bits/stdc++.h>
using namespace std;
 
double s(int A,int B,int C)
{
    double a=A,b=B,c=C;
    if(1/b/b-2*c/a/b<=0) return 0;
    double maxx=a/b+sqrt(a*a/b/b-2*a*c/b),minx=a/b-sqrt(a*a/b/b-2*a*c/b);
    maxx=maxx*maxx/2/b-c*maxx/b-maxx*maxx*maxx/6/a;
    minx=minx*minx/2/b-c*minx/b-minx*minx*minx/6/a;
    return maxx-minx;
}
 
int main()
{
    int T,A,B,C;
    cin>>T;
    for(int i=0;i<T;++i)
    {
        cin>>A>>B>>C;
        cout<<s(A,B,C)<<endl;
    }
    return 0;
}

发表于 2021-08-11 17:17:23 回复(0)