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("\n");
    }

    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(")");
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM