HDU - 3556 - Continued Fraction

先上题目:

Continued Fraction

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 332    Accepted Submission(s): 106


Problem Description
Dumbear loves numbers very much.
One day Dumbear found that each number can be expressed as a continued fraction. See below.

Formally, we say a number k can be expressed as a continued faction if

where a 0, a 1, …, a n are positive integers except that a 0 maybe be 0 and a n cannot be 1.
Dumbear also found a sequence which looks like the Farey sequence. Initially the sequence and if we insert an element between all the two adjacent element , in D i, then we get a sequence D i+1. So you can see and Assume initially you are on the element in D 0, and if now you are on the element k in D i, then if you go left(‘L’)(or right(‘R’)) you will be on the left(or right) element of k in D i+1. So a sequence composed of ‘L’ and ‘R’ denotes a number. Such as ‘RL’ denotes the number 

Now give you a sequence composed of ‘L’ and ‘R’, you should print the continued fraction form of the number. You should use ‘-‘ to show the vinculum(the horizontal line), you should print one space both in front and back of ‘+’, and all parts up or down the vinculum should be right aligned. You should not print unnecessary space, ‘-‘ or other character. See details in sample.
 

 

Input
There are several test cases in the input.
For each test case, there is a single line contains only a sequence composed of ‘L’ and ‘R’. The length of the sequence will not exceed 10000.
The input terminates by end of file marker.
 

 

Output
For each test case, output the continued fraction form of the number which the input sequence denotes. The total amount of output will not exceed 4MB.
 

 

Sample Input
LR
RL
 

 

Sample Output
           1
0 + -----
           1
      1 + -
           2
     1
1 + -
     2
 
    题意:给出一个只有L和R的字符串,根据它给出的定义移动,然后将最终的结果按照他给出的那种分式输出。
    模拟+找规律。首先先根据它的定义模拟它的移动,然后可以根据自己的分析求出a[]数组的每一项是多少,然后在按照它的格式输出。这里求a[]数组分析一下就可以知道怎么怎么求了,然后关于输出,通过前后项的长度关系就可以得出要输出多少个空格多少'-'了,但是这样做的话直接提交可能会wa,这里可以通过输出前几项找一下规律。将L,LL,LR,LLL,LLR,LRL,LRR以及R,RL,RR,RLL,RLR,RRL,RRR(也就是前几项的变化的输有情况)输出,然后通过观察,我们可以发现,对于第2项开始,如果当前项等于前一项,那么a[tot]++,否则a[tot]--;tot++;a[tot]=2;当前其实如果写得好的话可以顺便把前一项的情况也包含在公式里面。然后直接构造a[],在打印,速度和准确性上面都会有保证。
 
上代码:
 
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <string>
 4 #include <algorithm>
 5 #define MAX 10002
 6 #define PUTS(M,x) for(int k=0;k<M;k++) putchar(x)
 7 #define ll long long
 8 using namespace std;
 9 
10 char c[MAX];
11 int l;
12 ll a[MAX];
13 char ss[MAX<<4][20];
14 int len[MAX];
15 int tot;
16 typedef struct{
17     ll fz,fm;
18 }fs;
19 
20 fs A[3],p;
21 
22 void cons(int l){
23     if(c[0]=='L'){
24         a[0]=0; a[1]=2; tot=1;
25     }else{
26         a[0]=2; tot=0;
27     }
28     for(int i=1;i<l;i++){
29         if(c[i]==c[i-1]) a[tot]++;
30         else{
31             a[tot]--;
32             a[++tot]=2;
33         }
34     }
35     tot++;
36 }
37 
38 int main()
39 {
40     int M;
41     //freopen("data.txt","r",stdin);
42     while(scanf("%s",c)!=EOF){
43         l=strlen(c);
44 //        A[0].fz=0;  A[0].fm=1;
45 //        A[1].fz=1;  A[1].fm=1;
46 //        A[2].fz=1;  A[2].fm=0;
47 //        for(int i=0;i<l;i++){
48 //            if(c[i]=='L'){
49 //                A[2]=A[1];
50 //            }else{
51 //                A[0]=A[1];
52 //            }
53 //            A[1].fz=A[0].fz+A[2].fz;
54 //            A[1].fm=A[0].fm+A[2].fm;
55 //        }
56 //        tot=0;
57 //        p=A[1];
58 //        while(1){
59 //            a[tot]=p.fz/p.fm;
60 //            sprintf(ss[tot],"%I64d",a[tot]);
61 //            tot++;
62 //            p.fz=p.fz%p.fm;
63 //            if(p.fz==0) break;
64 //            else if(p.fz==1){
65 //                a[tot]=p.fm;
66 //                sprintf(ss[tot],"%I64d",a[tot]);
67 //                tot++;
68 //                break;
69 //            }
70 //            swap(p.fz,p.fm);
71 //        }
72         cons(l);
73         for(int i=0;i<tot;i++) sprintf(ss[i],"%I64d",a[i]);
74         len[tot-1]=strlen(ss[tot-1]);
75         len[tot-2]=strlen(ss[tot-2]) + 3 + strlen(ss[tot-1]);
76         for(int i=tot-3;i>=0;i--){
77             len[i]=strlen(ss[i]) + 3 + len[i+1];
78         }
79 
80 //        for(int i=0;i<tot;i++) printf("%I64d ",a[i]);
81 //        printf("\n");
82 //        for(int i=0;i<tot;i++) printf("%d ",len[i]);
83 //        printf("\n");
84         M=len[0];
85         for(int i=0;i<tot-1;i++){
86             PUTS(M-1,' ');  putchar('1');   putchar('\n');
87             PUTS(M-len[i],' ');
88             printf("%s + ",ss[i]);
89             PUTS(len[i+1],'-');
90             putchar('\n');
91         }
92         PUTS(M-(int)strlen(ss[tot-1]),' ');
93         printf("%s",ss[tot-1]);
94         printf("\n");
95     }
96     return 0;
97 }
/*3556*/

 

 

转载于:https://www.cnblogs.com/sineatos/p/3917222.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值