PAT (Basic Level) Practise (中文)-1034. 有理数四则运算(20) http://www.patest.cn/contests/pat-b-practise/1034
本题要求编写程序,计算2个有理数的和、差、积、商。
输入格式:
输入在一行中按照“a1/b1 a2/b2”的格式给出两个分数形式的有理数,其中分子和分母全是整型范围内的整数,负号只可能出现在分子前,分母不为0。
输出格式:
分别在4行中按照“有理数1 运算符 有理数2 = 结果”的格式顺序输出2个有理数的和、差、积、商。注意输出的每个有理数必须是该有理数的最简形式“k a/b”,其中k是整数部分,a/b是最简分数部分;若为负数,则须加括号;若除法分母为0,则输出“Inf”。题目保证正确的输出中没有超过整型范围的整数。
输入样例1:
2/3 -4/2
输出样例1:
2/3 + (-2) = (-1 1/3) 2/3 - (-2) = 2 2/3 2/3 * (-2) = (-1 1/3) 2/3 / (-2) = (-1/3)
输入样例2:
5/3 0/6
输出样例2:
1 2/3 + 0 = 1 2/3 1 2/3 - 0 = 1 2/3 1 2/3 * 0 = 0 1 2/3 / 0 = Inf
分析:本题目没有思维的难度,只是可能处理起来有点啰嗦烦人,所以建议一定要单独写成小功能函数。
比如:
1. 输出的每个有理数必须是该有理数的最简形式“k a/b”,其中k是整数部分,a/b是最简分数部分
2. 若为负数,则须加括号
3. 若除法分母为0,则输出“Inf”。
1 #include<stdio.h> 2 3 void jianhua(long long *fenzi,long long *fenmu) 4 { 5 if(*fenzi==0 || *fenmu==0) 6 { 7 *fenzi=0,*fenmu=1; 8 return; 9 } 10 11 int flag1=0,flag2=0 ;// 1负数 2正数 12 if(*fenzi<0) flag1=1,*fenzi=0-*fenzi; 13 if(*fenmu<0) flag2=1,*fenmu=0-*fenmu; 14 15 long long max=0,min=0; 16 if(*fenzi>*fenmu) max=*fenzi,min=*fenmu; 17 else min=*fenzi,max=*fenmu; 18 while(max%min) 19 { 20 if(max-min>min) 21 max=max-min; 22 else 23 { 24 min=max-min; 25 max=max-min; 26 } 27 } 28 *fenzi/=min,*fenmu/=min; 29 30 if(flag1) *fenzi=0-*fenzi; 31 if(flag2) *fenmu=0-*fenmu; 32 if(*fenmu<0) *fenzi=0-*fenzi,*fenmu=0-*fenmu; 33 34 return; 35 } 36 37 void outlook(long long a,long long b,int i,long long c) //输出 函数 38 { 39 int flag=0; 40 if(a<0) {flag=1;a=0-a;printf("(-");} 41 42 if(i==3 && c==0) printf("Inf"); //i==3时代表除法运算 43 else if(a==0) printf("0"); //分子为0,即数==0 44 else if(a/b) { if(a%b) printf("%lld %lld/%lld",a/b,a%b,b); 45 else printf("%lld",a/b); 46 }else printf("%lld/%lld",a,b); //可以整除,即简化为整数 47 48 if(flag) printf(")"); 49 } 50 51 52 int main() 53 { 54 long long *pfenzi=0,*pfenmu=0; 55 long long a=0,b=1,c=0,d=1,fenzi=0,fenmu=1; //因为两个整数相乘,可能超出int范围,所以使用了long long 56 scanf("%lld/%lld %lld/%lld",&a,&b,&c,&d); 57 58 pfenzi=&a; 59 pfenmu=&b; 60 jianhua(pfenzi,pfenmu); //第一个数 61 pfenzi=&c; 62 pfenmu=&d; 63 jianhua(pfenzi,pfenmu); //第二个数 64 char op[4]={'+','-','*','/'}; 65 for(int i=0;i<4;i++) 66 { 67 //'+','-','*','/' 依次处理 68 if(0==i) { fenzi=a*d+c*b; fenmu=b*d; } 69 else if(1==i) { fenzi=a*d-c*b; fenmu=b*d; } 70 else if(2==i) { fenzi=a*c; fenmu=b*d; } 71 else { fenzi=a*d; fenmu=b*c; } 72 pfenzi=&fenzi; 73 pfenmu=&fenmu; 74 jianhua(pfenzi,pfenmu); // 简化当前处理运算的结果 75 76 77 // 格式输出 78 if(i) printf(" "); 79 outlook(a,b,i,1); //第一个数 80 printf(" %c ",op[i]); // 运算符 81 outlook(c,d,i,1); //第二个数 82 printf(" = "); 83 outlook(fenzi,fenmu,i,c); //结果 84 } 85 86 return 0; 87 }
好讨厌这道题。。。难度不高,却这么复杂。。。好考验耐心。。。