zoukankan      html  css  js  c++  java
  • P2026 求一次函数解析式

    题目描述 给定两个整点的坐标,求它们所在直线的函数解析式(一次函数)。

    输入格式 输入共两行。第一行有两个整数x1,y1。表示第一个整点的坐标为(x1,y1)第二行有两个整数x2,y2。表示第二个整点的坐标为(x2,y2)

    输出格式 输出共一行,即这个函数解析式。

    输入输出样例

    输入 #1
    3 6
    2 4
    
    
    输出 #1
    y=2x
    
    
    输入 #2
    3 5
    2 7
    输出 #2
    y=-2x+11
    输入 #3
    3 -1
    5 -2
    输出 #3
    y=-1/2*x+1/2
    哇连复制键本身都能粘贴的吗这么神奇吗

    首先,求一次函数解析式的数学步骤应该人人皆知,即对于经过点(x1,y1),(x2,y2)的一次函数y=kx+b,有
                k=(y2-y1)/(x2-x1),
                b=y1-kx1.
    我觉得这个题太好做了,然而看到第三组数据的时候,我惊呆了。
    要分数的啊!!!这就表明double是绝对不行的了!
    看了看题解(发誓没有抄袭,借鉴都没有),里面的大佬们都用了各种花里胡哨的解法,好几个if语句写了将近两行,明显是在判断是不是需要分数。
    然而,作为学过面向对象程序设计的我,觉得用结构体是个不错的选择!(面向对象中的“类”和结构体非常相像,然而noi只教结构体,我曾大为不满)
    我们可以用一个结构体"fs"表示分数,在里面实现各种分数的各种功能。包括两个变量分子和分母以及输出函数。但是需要注意的是,上述求k和b的算式中有分数与整数的乘法(kx1)以及分数和分数的减法(y1-kx1)因此需要编写结构体fs的operator*(int)和operator-(fs)函数。
    输出函数output,在里面完成各种判断,例如当分子为0是不输出,分母为1时只输出分子,其他情况输出"分子/分母”的形式。
    同时,这里也有一个需要注意的地方。我们要在输出分数时输出其符号。但是对于k,若分数值为正,不用输出正号,但b就要输出了(负号就都一样了,都要输出)。于是需要告诉output函数一个参数,表示需不需要输出正符号。
    当然,最重要的是求最大公约数的函数,使分数能够对于输入的分子和分母进行约分,以及分数相减时的通分。
    代码如下:
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    using namespace std;
    int gcd(int a,int b)
    {
        return (a%b==0)?b:gcd(b,a%b);//辗转相除法 
    }
    struct point
    {
        int x;
        int y;
    }p1,p2;
    struct fs
    {
        int fenzi;
        int fenmu;
        bool zheng;//正数或0为true,负数为false 
        void yue(int &a,int &b)//模拟约分,因为要修改分子和分母本身的值,因此用引用。 
        {
            int p=gcd(a,b);
            a/=p;
            b/=p;
        }
        fs(int a,int b)//a/b,初始化的构造函数 
        {
            if(a*b>0) zheng=true;//判断正负 
            else zheng=false;
            if(gcd(a,b)==1)//不用约分 
            {
                fenzi=a;
                fenmu=b;
            }
            else//其实不用再特判一下,直接除就行 
            {
                int p=gcd(a,b);
                a/=p;
                b/=p;
                fenzi=a;
                fenmu=b;
            }
        }
        fs operator*(int a)
        {
            fs r(this->fenzi*a,fenmu);
            return r;
        }
        fs operator-(fs a)
        {
            fs r(fenzi*a.fenmu-fenmu*a.fenzi,fenmu*a.fenmu);//a/b-c/d==(ad-bc)/bd
            return r;
        }
        void output(bool NEED_TO_OUTPUT_ZHENG)//NEED_TO_OUTPUT_ZHENG表示是否需要在分数值为正时输出正号 
        {
            if(fenzi==0) return;//分子是0,不用输出 
            yue(fenzi,fenmu);//再约分一下保险 
            if(zheng==true&&NEED_TO_OUTPUT_ZHENG==true)//正数且要输出正号 
            {
                cout<<"+";
            }
            else if(zheng==false)//负数 
            {
                cout<<"-";
            }
            if(fenmu==1)
            {
                if(fenzi==1||fenzi==-1) return;//题目中,只要是分数,后面就跟乘号,因此这样能过 
                else cout<<abs(fenzi);//符号已经输出了 
            }
            else
            {
                cout<<abs(fenzi)<<"/"<<abs(fenmu);//最普通的情况 
            }
        }
    };
    int main()
    {
        cin>>p1.x>>p1.y>>p2.x>>p2.y;
        fs k(p1.y-p2.y,p1.x-p2.x);
        fs temp_y(p1.y,1);//临时的一个分数形式的y1,能够让其成功调用operator-函数 
        fs b=temp_y-(k*p1.x);
        cout<<"y=";
        k.output(0);//不输出正号 
        if(k.fenmu!=1)
        {
            cout<<"*";
        }
        cout<<"x";
        b.output(1);//输出正号 
        return 0;
    }
    
    
    
    
    
  • 相关阅读:
    python2和python3的import区别
    设计模式:装饰器(Decorator)模式
    设计模式:组合(Composite)模式
    设计模式:策略模式
    设计模式:桥接(Bridge)模式
    设计模式:抽象工厂模式
    设计模式:Builder模式
    设计模式:原型模式
    设计模式:单例模式
    设计模式:工厂方法
  • 原文地址:https://www.cnblogs.com/jiangyuechen/p/12380325.html
Copyright © 2011-2022 走看看