zoukankan      html  css  js  c++  java
  • 1034. 有理数四则运算(20)

    参考: http://www.jianshu.com/p/5303f2431f05

    原题: https://www.patest.cn/contests/pat-b-practise/1034

    思路: 本题其实不难, 关键是测试点刁钻. 改了老半天, 在
    网上找了很多资料, 最终才AC

    测试点2: 测试和0相关的输入
    测试点3: 测试结果为负负的情况

    本题, 在PAT服务器上进行提交测试, 发现使用相减法求最大公约数不能AC,
    原因不明, 而使用辗转相除法可以AC, 下面的实现, 可以做到不需要求带负
    数的最大公约数问题, 但是带0求最大公约数不可避免.

    题目虽然说, 各种计算不超过int, 但是为了方便, 比如计算乘法, 无需先通分
    而是直接乘, 所以尽量使用long.

    实现:

    #include <stdio.h>
    
    long getgcd(long a, long b);
    void printfrac(long a, long b);
    
    int main (void) {
    	long a1;
    	long b1;
    	long a2;
    	long b2;
        char op[4] = {'+', '-', '*', '/'};
    	int i;
    
    	scanf("%ld/%ld %ld/%ld", &a1, &b1, &a2, &b2);
        for(i = 0; i < 4; i++) {
            printfrac(a1, b1);
    		printf(" %c ", op[i]);
            printfrac(a2, b2);
    		printf(" = ");
    		// 我们使用的是long, 这里不用同分, 直接计算
            switch (op[i]) {
                case '+':
    				printfrac(a1 * b2 + a2 * b1, b1 * b2); 
    				break;
                case '-':
    				printfrac(a1 * b2 - a2 * b1, b1 * b2);
    				break;
                case '*':
    				printfrac(a1 * a2, b1 * b2);
    				break;
                case '/':
    				printfrac(a1 * b2, b1 * a2);
    				break;
            }
            printf("
    ");
        }
    
        return 0;
    }
    
    
    long getgcd (long a, long b) {
    	// 用其它求gcd的方法, 很可能导致
    	// 后两个测试点超时, 原因不明
    	long r;
        while ((r = a % b)) {
            a = b;
            b = r;
    	}
    	
        return b;
    }
    
    
    void printfrac (long a, long b) {
    	/*
    		这里的a, b有多种情况, 正正, 正负, 负负都有可能
    		再下面判断符号时, 充分利用了负负的正的思想
    	*/
        if (b == 0) {
    		printf("Inf");
    		return;
    	}
    
        int sign = 1;
    	long gcd;
        if (a < 0) {
    		a = -a;
    		sign = sign * -1;
    	}
        if (b < 0) {
    		b = -b;
    		sign = sign * -1;
    	}
    	gcd = getgcd(a, b);
    	a = a / gcd;
    	b = b / gcd;
    
        if (sign == -1) printf("(-");
    	if (b == 1) {
    		printf("%ld", a); 	// 整数
    	} else if (a > b) {
    		printf("%ld %ld/%ld", a / b, a % b, b);
    	} else {
    		printf("%ld/%ld", a, b); // a < b
    	}
    	if (sign == -1) printf(")");
    }
    
    
  • 相关阅读:
    AutoLISP引线序号球
    2011年4月1日星期五
    AutoLISP绘制表格
    AutoLISP绘制玻璃门
    AutoLISPDCL对话框设计
    AutoLISP虚拟线变化图
    AutoLISP切圆动画
    盖章
    AutoLISP第一个DCL窗体
    jquery cookie插件使用
  • 原文地址:https://www.cnblogs.com/asheng2016/p/7979386.html
Copyright © 2011-2022 走看看