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
Description

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 a0a1a2, ... are integers and a1a2, ... > 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.

Input

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.

Output

For each test case, display the case number followed by the continued fraction representation of r1 + r2r1r2r1×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).

Sample Input

4 3
5 1 1 2
5 2 2
0 0

Sample Output

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:

  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 }
View Code

猜你喜欢

转载自www.cnblogs.com/ymzjj/p/9703191.html