zoukankan      html  css  js  c++  java
  • PTA 乙级 1034 有理数四则运算 (20分) C/C++

     坑多,坑多

    分为几个部分:

    加工:将数字化为符合格式要求的形式

    化简:使分母始终为正,分子分母化为最简(注意最大公约数为零的情况,否则可能编译无法通过,然后报浮点错误

    求最大公约数:递归利用辗转相除法求最大公约数

    加法,减法,除法,乘法运算

    辗转相除法

    1 long long gcd(long long x, long long y) {
    2     long long z = 0;
    3     while (x % y) {
    4         z = x % y;
    5         x = y;
    6         y = z;
    7     }
    8     return z;
    9 }

    注意:

    • 测试点3:
      • 用long long类型存储分子分母,题中只是说正确的输出中没有超过整形范围的整数,但乘法可能会出现超过整形范围的整数,以致测试点3报浮点错误
      • 记得考虑分子分母绝对值相等的情况,否则会报答案错误
      • 还要注意分子分母负负得正(保持分母始终为正数),否则会报答案错误    
    • 测试点2:注意用空间复杂度小的方法求最大公约数,不可以用枚举法,会超时

    C/C++

     1 #include<iostream>
     2 #include<string>
     3 
     4 using namespace std;
     5 
     6 typedef struct {
     7     /*假分数分子*/
     8     long long men;
     9     /*真分数分子*/
    10     long long rmen;
    11     /*分母*/
    12     long long den;
    13     /*真数*/
    14     long long ant;
    15     /*最终输出形式*/
    16     string s;
    17 }Num;
    18 
    19 long long gcd(long long x, long long y) {    //求最大公约数
    20     return y == 0 ? x : gcd(y, x % y);
    21 }
    22 
    23 int simplify(Num* n) {                        //化简
    24     if (n->den < 0)n->men = -(n->men), n->den = -(n->den);    //保持分母始终为正
    25     long long rem = gcd(abs(n->men), abs(n->den));
    26     if (rem == 0) return 0;                    //出现最大公约数为零的情况(没有最大公约数),直接返回
    27     n->men /= rem;
    28     n->den /= rem;
    29     return 0;
    30 }
    31 
    32 int process(Num* n) {
    33     if (n->den == 0) {                        //分母为零的情况
    34         n->s = "Inf";
    35         return 0;
    36     }
    37     simplify(n);
    38     n->ant = 0;    
    39     if ((long long)abs(n->men) >= n->den) {    //假分数(注意分子分母相等的情况,否则测试点3过不了)
    40         if (n->men % n->den == 0) {            //可以除尽,化为整数
    41             n->ant = n->men / n->den;
    42             n->s = to_string(n->ant);
    43         }
    44         else{                                //化为带分数
    45             n->ant = n->men / n->den;
    46             n->rmen = (long long)abs(n->men) - ((long long)abs(n->ant) * n->den);
    47             n->s = to_string(n->ant) + ' ' + to_string(n->rmen) + '/' + to_string(n->den);
    48         }
    49     }
    50     else if (n->men == 0) {                    //分子为零
    51         n->s = "0";
    52     }
    53     else {                                    //真分数
    54         n->s = to_string(n->men) + '/' + to_string(n->den);
    55     }                                        //负数带符号
    56     if (n->men < 0 || n->ant < 0)n->s = '(' + n->s + ')';
    57     return 0;
    58 }
    59 
    60 void plusnum(Num* x, Num* y, Num* z) {        //加法
    61     z->den = x->den * y->den;
    62     z->men = x->men * y->den + y->men * x->den;
    63     process(z);
    64 }
    65 
    66 void minusnum(Num* x, Num* y, Num* z) {        //减法
    67     z->den = x->den * y->den;
    68     z->men = x->men * y->den - y->men * x->den;
    69     process(z);
    70 }
    71 
    72 void multiplynum(Num* x, Num* y, Num* z) {    //乘法
    73     z->men = x->men * y->men;
    74     z->den = x->den * y->den;
    75     process(z);
    76 }
    77 
    78 void dividenum(Num* x, Num* y, Num* z) {    //除法
    79     z->men = x->men * y->den;
    80     z->den = x->den * y->men;
    81     process(z);
    82 }
    83 
    84 int main() {
    85     Num a, b, ret;
    86     scanf_s("%lld/%lld %lld/%lld", &a.men, &a.den, &b.men, &b.den);    //vs为scanf_s
    87     process(&a);
    88     process(&b);
    89     plusnum(&a, &b, &ret);
    90     cout << a.s << " + " << b.s << " = " << ret.s << endl;
    91     minusnum(&a, &b, &ret);
    92     cout << a.s << " - " << b.s << " = " << ret.s << endl;
    93     multiplynum(&a, &b, &ret);
    94     cout << a.s << " * " << b.s << " = " << ret.s << endl;
    95     dividenum(&a, &b, &ret);
    96     cout << a.s << " / " << b.s << " = " << ret.s << endl;
    97     return 0;
    98 }

    哈哈,还蛮快的

  • 相关阅读:
    姐姐的vue(1)
    LeetCode 64. Minimum Path Sum 20170515
    LeetCode 56. 56. Merge Intervals 20170508
    LeetCode 26. Remove Duplicates from Sorted Array
    LeetCode 24. Swap Nodes in Pairs 20170424
    LeetCode 19. Remove Nth Node From End of List 20170417
    LeetCode No.9 Palindrome Number 20170410
    LeetCode No.8. String to Integer (atoi) 2017/4/10(补上一周)
    LeetCode No.7 Reverse Integer 2017/3/27
    LeetCode No.4 Median of Two Sorted Arrays 20170319
  • 原文地址:https://www.cnblogs.com/SCP-514/p/13363914.html
Copyright © 2011-2022 走看看