HDU 1274 展开字符串

地址:http://acm.hdu.edu.cn/showproblem.php?pid=1274

不太懂,,先发表别人的。。。慢慢研究。。。。

算法:

用了最直接,最暴力的方法。一层层展开。从右到左,遇到(或是数字就展开。

一开始想了很多,想得很复杂,但都没办法想下去。于是,就用最简单的方法,直接AC了。原以为是超时的。

幸好数据不是很大。用了两个字符数组,一个用于存重复内容。一个存后辍

具体做法。

统一性。

1。没括号的,数字+字母,字母这两种类型。当成数字+(字母),(字母)类型。重复内容,直接是单个字母。

2。没数字的,字母,(字符串),当成1+字母,1+(字符串)类型。重复次数是1次。

这样就把上面的所有情况统一化了。之后只要一个函数就可以完成每一次的重复内容的。

下面是AC代码:

  1 #include<stdio.h>
  2 #include<string.h>
  3     
  4 
  5 char str[3000001];
  6 char ans[1000000];
  7 char help[100000];
  8 int n,len;
  9 
 10 void solve_other(int sum,char help[],char ans[],int k)
 11 {
 12     int p,q;
 13     for(p=1;p<=sum;p++)
 14     {
 15         for(q=0;help[q]!=0;q++)
 16         {
 17             str[k++]=help[q];
 18         }
 19     }
 20     for(q=0;ans[q]!=0;q++)
 21     {
 22         str[k++]=ans[q];
 23     }            
 24     len=k;
 25 }
 26 
 27 void solve()
 28 {
 29     int i,j;
 30     int p,q,k;
 31     int sum;
 32     for(i=n-1;i>=0;i--)
 33     {
 34         if(str[i]=='(')
 35         {
 36             for(j=i+1;;j++)
 37             {
 38                 if(str[j]==')')
 39                 {
 40                     help[j-i-1]=0;
 41                     break;
 42                 }
 43                 help[j-i-1]=str[j];
 44             }
 45             sum=0;
 46             p=1;
 47             while(i-1>=0&&str[i-1]>='0'&&str[i-1]<='9')
 48             {
 49                 sum=(str[i-1]-'0')*p+sum;
 50                 p=p*10;
 51                 i--;
 52             }
 53             if(sum==0) sum=1;
 54             for(q=j+1;q<len;q++)
 55             {
 56                 ans[q-j-1]=str[q];
 57             }
 58             ans[q-j-1]=0;
 59             k=i;
 60             solve_other(sum,help,ans,k);
 61 
 62         }
 63         else if(str[i]>='0'&&str[i]<='9')
 64         {
 65             sum=0;
 66             p=1;
 67             j=i+1;
 68             while(i>=0&&str[i]>='0'&&str[i]<='9')
 69             {
 70                 sum=(str[i]-'0')*p+sum;
 71                 p=p*10;
 72                 i--;
 73             }
 74             i++;
 75             if(sum==0) sum=1;
 76             if(j<n)
 77             {
 78                 help[0]=str[j];
 79                 help[1]=0;
 80                 for(p=j+1;p<len;p++)
 81                 {
 82                     ans[p-j-1]=str[p];
 83                 }
 84                 ans[p-j-1]=0;
 85                 solve_other(sum,help,ans,i);
 86             }
 87         }
 88     }
 89     str[len]=0;
 90 }
 91 
 92 int main()
 93 {
 94     int k;
 95 
 96     scanf("%d",&k);
 97     while(k--)
 98     {
 99         scanf("%s",str);
100         n=strlen(str);
101         len=n;
102         solve();
103         printf("%s/n",str);
104 
105     }
106     return 0;
107 }

法二:

 1 #include "stdio.h"
 2 #include "string.h"
 3 
 4 char sss[260];
 5 
 6 int kh[260];  //括号匹配
 7 
 8 int digit(char c){
 9     return c >= '0' && c <= '9';
10 }
11 
12 void print(int st, int ed){
13     int i, j;
14 
15     for(i=st; i<=ed; ){
16 
17         if(digit(sss[i])){
18             if(sss[i+1] == '('){ //3(abc...) 或者 1(abc...)
19                 for(j=0; j<sss[i]-'0'; j++)
20                     print(i+2, kh[i+1]-1);
21                 i = kh[i+1] + 1;
22             }else{ //3abc...
23                 for(j=0; j<sss[i]-'0'; j++)
24                     printf("%c", sss[i+1]);
25                 i += 2;
26             }
27                     
28         }else{
29             if(sss[i] == '('){ //(abc...)
30                 print(i+1, kh[i]-1);
31                 i = kh[i]+1;
32             }else //abc...
33                 printf("%c", sss[i++]);
34         }
35     
36     }
37 }
38 
39 void main(){
40     int n;
41     int i;
42     int stack[251];
43     int top;
44 
45     freopen("in.txt", "r", stdin);
46 
47     scanf("%d", &n);
48     while(n--){
49         getchar();
50         scanf("%s", sss);
51         top = 0;
52         for(i=strlen(sss)-1; i>=0; i--){
53             if(sss[i] == ')')
54                 stack[top++] = i;
55             if(sss[i] == '('){
56                 top--;        
57                 kh[i] = stack[top];
58             }
59         }
60 
61         print(0, strlen(sss)-1);
62         printf("\n");
63     }
64 }

法三:

 1 #include <iostream>
 2 using namespace std;
 3 char input[250005];
 4 char str[250005];
 5 int main() 
 6 {
 7     int cas;
 8 #ifndef ONLINE_JUDGE
 9     freopen("in.txt", "r", stdin);
10 #endif
11     scanf("%d", &cas);
12     while (cas--) 
13     {
14         scanf("%s", input);
15         int len;
16         while (1) 
17         {
18             int flag = 0;
19             int c = 0;
20             int i, j, k;
21             len = strlen(input);
22             for (i = 0; i < len; ++i)
23             {
24                 if (input[i] >= 'a' && input[i] <= 'z') 
25                 {
26                     str[c++] = input[i];
27                 } 
28                 else if (input[i] >= '0' && input[i] <= '9') 
29                 {
30                     int cnt = 0;
31                     while (input[i] >= '0' && input[i] <= '9') 
32                     {
33                         cnt *= 10;
34                         cnt += input[i] - '0';
35                         ++i;
36                     }
37                     if (input[i] != '(') 
38                     {
39                         while (cnt--) 
40                         {
41                             str[c++] = input[i];
42                         }
43                     }
44                     else 
45                     {
46                         int t = 1;
47                         int temp = i + 1;
48                         while (t != 0) {
49                             if (input[temp] == '(') 
50                             {
51                                 ++t;
52                             }
53                             if (input[temp] == ')') 
54                             {
55                                 --t;
56                             }
57                             ++temp;
58                         }
59                         for (j = 0; j < cnt; ++j) 
60                         {
61                             for (k = i + 1; k < temp - 1; ++k) 
62                             {
63                                 str[c++] = input[k];
64                                 if (input[k] == '(' || input[k] == ')' || (input[k] >= '0' && input[k] <= '9')) 
65                                 {
66                                     flag = 1;
67                                 }
68                             }
69                         }
70                         i = temp - 1;
71                     }
72                 }
73             }
74             str[c] = 0;
75             memcpy(input, str, sizeof(str));
76             if (flag == 0) 
77             {
78                 break;
79             }
80         }
81         cout << str << endl;
82     }
83     return 0;
84 }

法四:

//一个很不错的递归题,我主要的过程就如一般的表达式求解,遇到左括号进入下层递归,
//否则一直按每个字母前面的数字决定其输出的次数,括号也是如此,而递归结束的标志
//则是遇到 右括号或者到字符串的结尾,注意每次递归结束需要返回下次遍历的序号

 1 #include<stdio.h>
 2  #include<ctype.h>
 3  #include<string.h>
 4  char s[260];
 5  int dfs(int ith)
 6  {
 7      int k,e;
 8      char c;
 9      for(c=s[ith++];ith<strlen(s)&&c!=')';c=s[ith++])//递归结束的条件是字符串结束或遇到右括号 
10      {
11          for(k=0;isdigit(c);c=s[ith++])
12              k=k*10+c-'0';
13          if(!k) k=1;
14          if(c=='('){
15              while(k--)
16                  e=dfs(ith);
17              ith=e;//重置ith的值,到下层递归结束的位置 
18          }
19          else{
20              while(k--)
21                  putchar(c);
22          }
23      }
24      if(c==')') return ith;//返回本次读到结尾的位置 
25  }
26  int main()
27  {
28      int n;
29      scanf("%d",&n);
30      while(n--)
31      {
32          scanf("%s",s);
33          dfs(0);//进入递归 
34          printf("\n");
35      }
36      return 0;
37  }

 

 

posted on 2012-08-18 21:24  mycapple  阅读(356)  评论(0编辑  收藏  举报

导航