2014-2015 ACM-ICPC East Central North America Regional Contest (ECNA 2014) A、Continued Fractions 【模拟连分数】
任意门:http://codeforces.com/gym/100641/attachments
Con + tin/(ued + Frac/tions)
- Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
- Total Submission(s): 217 Accepted Submission(s): 27
The (simple) continued fraction representation of a real number r is an expression obtained by an iterative process of representing r as a sum of its integer part and the reciprocal of another number, then writing this other number as the sum of its integer part and another reciprocal, and so on. In other words, a continued fraction representation of r is of the form
where a0, a1, a2, ... are integers and a1, a2, ... > 0. We call the ai-values partial quotients. For example, in the continued fraction representation of 5.4 the partial quotients are a0 = 5, a1 = 2, and a2 = 2. This representation of a real number has several applications in theory and practice.
While irrational numbers like √2 (sqrt(2)) require an infinite set of partial quotients, any rational number can be written as a continued fraction with a unique, finite set of partial quotients (where the last partial quotient is never 1 in order to preserve uniqueness). Given two rational numbers in continued fraction representation, your task is to perform the four elementary arithmetic operations on these numbers and display the result in continued fraction representation.
Each test case consists of three lines. The first line contains two integers n1 and n2, 1 ≤ ni ≤ 9 specifying the number of partial quotients of two rational numbers r1 and r2. The second line contains the partial quotients of r1 and the third line contains the partial quotients of r2. The partial quotients satisfy |a0| ≤ 10 and 0 < ai ≤ 10, the last partial quotient will never be 1, and r2 is non-zero. A line containing two 0's will terminate input.
For each test case, display the case number followed by the continued fraction representation of r1 + r2, r1- r2, r1×r2, and r1/r2 in order, each on a separate line. Use 64-bit integers for all of your calculations (long long in C++ and long in Java).
4 3
5 1 1 2
5 2 2
0 0
Case 1:
11
0 5
30 4 6
1 27
题意概括:
给一串 a 按照连分数定义算出 r1;给一串 b 按照连分数定义算出 r2;
最后按照连分数的格式 输出 r1 + r2, r1- r2, r1 * r2, r1 / r2;
解题思路:
模拟一遍连分数计算过程算出 r1 和 r2;
然后判断 r1 r2 是分数还是整数(因为是 LL ,作除法时对精度有要求)
模拟求连分数的逆过程输出 r1 r2 四则运算的结果。
AC code:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cmath> 5 #include <cstring> 6 #define LL long long 7 using namespace std; 8 const int MAXN = 26; 9 LL x1, x2, y, y2; 10 LL A[MAXN], B[MAXN]; 11 int N, M; 12 13 LL Gcd(LL a, LL b) 14 { 15 if(b == 0) return a; 16 return Gcd(b, a%b); 17 } 18 19 void solve1() //求 r1 分数 20 { 21 LL t = 0; 22 x1 = 1, y = A[N-1]; 23 for(int i = N-2; i > 0; i--){ 24 x1 = x1+A[i]*y; 25 t = y; 26 y = x1; 27 x1 = t; 28 } 29 x1 = x1+A[0]*y; 30 } 31 32 void solve2() //求 r2 分数 33 { 34 LL t = 0; 35 x2 = 1, y2 = B[M-1]; 36 for(int i = M-2; i > 0; i--){ 37 x2 = x2+B[i]*y2; 38 t = y2; 39 y2 = x2; 40 x2 = t; 41 } 42 x2 = x2+B[0]*y2; 43 } 44 45 void ppt(LL a, LL b) //输出连续分式(求分数的逆过程) 46 { 47 LL gg = Gcd(a, b); 48 a /= gg; 49 b /= gg; 50 if(b < 0){ //分母小于零时,模不小于零 51 a*=-1; 52 b*=-1; 53 } 54 LL tmp = (a%b+b)%b; //小数部分 55 LL a0 = (a-tmp) / b; //整数部分 56 printf("%lld", a0); 57 a = tmp; //处理剩下的小数部分 58 59 swap(a, b); //分子分母倒置 60 while(b){ 61 tmp = a/b; 62 printf(" %lld", tmp); 63 a=a%b; 64 swap(a, b); 65 } 66 puts(""); 67 } 68 69 int main() 70 { 71 int T_case = 0; 72 while(~scanf("%d%d", &N, &M) && (N+M)){ 73 for(int i = 0; i < N; i++){ 74 scanf("%lld", &A[i]); 75 } 76 for(int i = 0; i < M; i++){ 77 scanf("%lld", &B[i]); 78 } 79 if(N == 1) x1 = A[0], y = 0; 80 else solve1(); 81 if(M == 1) x2 = B[0], y2 = 0; 82 else solve2(); 83 84 printf("Case %d:\n", ++T_case); 85 //加法 86 87 if(y == 0 || y2 == 0){ //存在一个整数 88 if(y != 0 && y2 == 0){ //r2 为整数 89 ppt(x2*y+x1, y); 90 } 91 else if(y2 != 0 && y == 0){ //r1 为整数 92 ppt(x1*y2+x2, y2); 93 } 94 else{ //两个都是整数 95 printf("%lld\n", x1+x2); 96 } 97 } 98 else{ //两个都是分数 99 ppt(x1*y2+x2*y, y*y2); 100 } 101 102 //减法 103 104 if(y == 0 || y2 == 0){ //存在一个整数 105 if(y != 0 && y2 == 0){ //r2 为整数 106 ppt(x1-x2*y, y); 107 } 108 else if(y2 != 0 && y == 0){ //r1 为整数 109 ppt(x1*y2-x2, y2); 110 } 111 else{ //两个都是整数 112 printf("%lld\n", x1-x2); 113 } 114 } 115 else{ //两个都是分数 116 ppt(x1*y2-x2*y, y*y2); 117 } 118 119 //乘法 120 121 if(y == 0 || y2 == 0){ //存在一个整数 122 if(y != 0 && y2 == 0){ //r2 为整数 123 ppt(x2*x1, y); 124 } 125 else if(y2 != 0 && y == 0){ //r1 为整数 126 ppt(x1*x2, y2); 127 } 128 else{ //两个都是整数 129 printf("%lld\n", x1*x2); 130 } 131 } 132 else{ //两个都是分数 133 ppt(x1*x2, y*y2); 134 } 135 136 //除法 137 138 if(y == 0 || y2 == 0){ //存在一个整数 139 if(y != 0 && y2 == 0){ //r2 为整数 140 ppt(x1, x2*y); 141 } 142 else if(y2 != 0 && y == 0){ //r1 为整数 143 ppt(x1*y2, x2); 144 } 145 else{ //两个都是整数 146 ppt(x1, x2); 147 } 148 } 149 else{ //两个都是分数 150 ppt(x1*y2, y*x2); 151 } 152 } 153 return 0; 154 }