首页 > 其他 > 详细

【Codeforces】Orz Panda Cup

时间:2019-10-25 17:45:13      阅读:86      评论:0      收藏:0      [点我收藏+]

大大出的题

大大经常吐槽没有人补,所以我决定做一个康康

 

A. APA of Orz Pandas

题意:给你一个包含+-*/%和()的表达式,让你把它转化成java里BigInteger的形式

大概就像这样 "a.add(b).remainder(M).multiply(d.substract(e.multiply(f)).add(g.divide(h))).multiply (BigInteger.ValueOf(233)) ... ..."

 

有意思的模拟题,不是很好写

首先要看清题,a+(b+c)应该输出为a.add(b.add(c))而不是a.add(b).add(c)

我之前看错题,使得这个题难度高了一点,但是那样也可以做,只需预处理无用括号即可

观察可以发现,不存在(a.add(b)).add(c)这种说法,也就是说,括号的本质作用是改变运算顺序,然后把括号里的表达式作为一个对象参与运算

那么就可以把括号里的东西看成一个变量,然后问题就转化为没有括号的表达式的处理

对于括号中的括号,可以把输出写成参数l和r的函数,功能为输出下标为[l,r]的子区间,然后递归处理

接下来的问题是找到输出序列中括号的包含范围,例如a+b*c要表示为a.add(b.multiply(c)),如何找到add右括号的位置

可以开一个栈

左括号可以直接压入

当压入右括号时,可以把左右括号中的所有运算符,包括括号全部湮灭

当压入+-时,可以把所有栈头的运算符湮灭,并令其右括号的位置在此运算符之前,但应在遇到左括号时停止

当压入*/%时,可以把栈头的*/%运算符湮灭,并令其右括号的位置在此运算符之前,但应遇到左括号或+-为止

 

代码:

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 char fc[5][10]={
 8     {a,d,d,0},
 9     {s,u,b,s,t,r,a,c,t,0},
10     {m,u,l,t,i,p,l,y,0},
11     {d,i,v,i,d,e,0},
12     {r,e,m,a,i,n,d,e,r,0}
13 };
14 int fs[256];
15 char s[11000];  int n;
16 char q[11000];  int p[11000],hd=0;
17 bool flg[11000];
18 int nxt[11000];
19 bool chck(char x){  return x==+||x==-||x==*||x==/||x==%||x==(||x==);}
20 bool chck1(char x){  return x==+||x==-||!x;}
21 bool chck2(char x){  return x==*||x==/||x==%||!x;}
22 void ot(int x,int y){
23     for(int i=x;i<=y;++i)if(s[i] && s[i]!=( && s[i]!=)){
24         if(!chck(s[i]))  printf("%c",s[i]);
25         else{
26             printf(".");
27             for(int j=0;fc[fs[(int)s[i]]][j];++j)  printf("%c",fc[fs[(int)s[i]]][j]);
28             printf("(");  ot(i+1,nxt[i]);  printf(")");
29             i=nxt[i];
30         }
31     }
32 }
33 void prvs(){
34     fs[+]=0,fs[-]=1,fs[*]=2,fs[/]=3,fs[%]=4;
35     hd=0;
36     for(int i=1;i<=n;++i)  flg[i]=false;
37     s[0]=0,s[n+1]=0;
38     for(int i=1;i<=n;++i)  nxt[i]=0;
39 }
40 int main(){
41     //freopen("ddd.in","r",stdin);
42     while(scanf("%s",s+1)!=EOF){
43         n=strlen(s+1);  prvs();
44         for(int i=1;i<=n;++i)if(chck(s[i])){
45             if(s[i]==)){
46                 bool mk1=false,mk2=false;
47                 for(;q[hd]!=(;--hd){
48                     if(q[hd]==+||q[hd]==-)  mk1=true;
49                     if(q[hd]==*||q[hd]==/||q[hd]==%)  mk2=true;
50                 }
51                 if((chck2(s[i+1])||chck2(s[p[hd]-1])) && !mk1){
52                     if(!mk2)  flg[i]=true,flg[p[hd]]=true;
53                     if(s[p[hd]-1]!=/&&s[p[hd]-1]!=%)  flg[i]=true,flg[p[hd]]=true;
54                 }
55                 if(s[i+1]==) && s[p[hd]-1]==()
56                     flg[i]=true,flg[p[hd]]=true;
57                 if(chck1(s[i+1]) && chck1(s[p[hd]-1]))
58                     flg[i]=true,flg[p[hd]]=true;
59                 nxt[p[hd]]=i;
60                 --hd;
61             }
62             else  q[++hd]=s[i];  p[hd]=i;
63         }
64         hd=0;
65         for(int i=1;i<=n;++i){
66             //if(flg[i])  s[i]=0;
67             if(s[i] && chck(s[i])){
68                 if(s[i]==()  q[++hd]=s[i],p[hd]=i;
69                 if(s[i]==)){
70                     for(;q[hd]!=(;--hd)  nxt[p[hd]]=i-1;
71                     --hd;
72                 }
73                 if(chck1(s[i])){
74                     for(;hd && q[hd]!=(;--hd)  nxt[p[hd]]=i-1;
75                     q[++hd]=s[i],p[hd]=i;
76                 }
77                 if(chck2(s[i])){
78                     for(;hd && q[hd]!=( && !chck1(q[hd]);--hd)  nxt[p[hd]]=i-1;
79                     q[++hd]=s[i],p[hd]=i;
80                 }
81             }
82         }
83         for(;hd;--hd)  nxt[p[hd]]=n;
84         /*for(int i=1;i<=n;++i)  cout<<i<<" ";
85         cout<<endl;
86         for(int i=1;i<=n;++i)  cout<<s[i]<<" ";
87         cout<<endl;
88         for(int i=1;i<=n;++i)  cout<<nxt[i]<<" ";
89         cout<<endl;*/
90         ot(1,n);  printf("\n");
91     }
92     return 0;
93 }
94 
95  
View Code

 

B. Brute Force of Orz Pandas

题意:

给你一个输出n层汉诺塔最优解的详细步骤的程序

技术分享图片

输入n和k,要求你输入当此程序输入为n时的第k行输入,如果k大于总行数则输出Orz

 

最开始的思路时数学/推公式/找规律解决,这样其实比较难搞

我们发现,直接运行给出的程序不可行是因为给出的程序会遍历每一种情况,而如果我们发现调用某个递归函数导致的输出大于当前查询的行数,完全可以跳过它

而对于每个递归的输出行数,可以由公式快速得到

那么类似在平衡树上查找第k大的方式

对于每一层,如果k小于第一个递归将输出的行数,那么进第一个递归,递归解决问题

如果等于第一个递归输出行数+1,说明找到我们的答案

如果大于第一个递归输出行数+1,就令k-=第一个递归输出行数+1,然后进第二个递归

对于n很大的情况,由于k不大,所有只有当函数中的size很小的时候才有可能涉及到中间的printf和第二个递归

那么可以预处理出最大的满足第一个递归输出行数>=所求行数的size,然后从这里开始递归即可

 

代码:

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 int rd(){int z=0,mk=1;  char ch=getchar();
 8     while(ch<0||ch>9){if(ch==-)mk=-1;  ch=getchar();}
 9     while(ch>=0&&ch<=9){z=(z<<3)+(z<<1)+ch-0;  ch=getchar();}
10     return z*mk;
11 }
12 const int oo=1000000007;
13 struct edg{int y,nxt,v;}e[41000];  int lk[210],ltp=1;
14 void ist(int x,int y,int v){
15     e[++ltp]=(edg){y,lk[x],v};  lk[x]=ltp;
16     e[++ltp]=(edg){x,lk[y],0};  lk[y]=ltp;
17 }
18 int n,m,o,a[210];  int s,t;
19 int lvl[210];
20 int q[210],hd=0;
21 int crt[210];
22 bool gtlvl(){
23     for(int i=s;i<=t;++i)  lvl[i]=0;
24     lvl[(q[(hd=1)]=s)]=1;
25     for(int k=1;k<=hd;++k){
26         crt[q[k]]=lk[q[k]];
27         for(int i=lk[q[k]];i;i=e[i].nxt)if(e[i].v && !lvl[e[i].y]){
28             lvl[e[i].y]=lvl[q[k]]+1;
29             q[++hd]=e[i].y;
30         }
31     }
32     return lvl[t];
33 }
34 int mxflw(int x,int y){
35     if(x==t)  return y;
36     int bwl=0,flw=0;
37     for(int i=crt[x];i && bwl<y;i=e[i].nxt)if(lvl[e[i].y]==lvl[x]+1 && e[i].v)
38         if((flw=mxflw(e[i].y,min(e[i].v,y-bwl)))){
39             e[i].v-=flw,e[i^1].v+=flw;
40             //cout<<e[i^1].y<<"->"<<e[i].y<<" "<<flw<<endl;
41             bwl+=flw;
42             if(!e[i].v)  crt[x]=e[i].nxt;
43         }
44     if(!bwl)  lvl[x]=0;
45     return bwl;
46 }
47 int dnc(){
48     int bwl=0,flw=0;
49     while(gtlvl())while((flw=mxflw(s,oo))){
50         bwl+=flw;
51         //printf("%d %d\n",bwl,flw);
52     }
53     return bwl;
54 }
55 void prvs(){
56     ltp=1;
57     for(int i=0;i<=n+m+1;++i)  lk[i]=0;
58 }
59 int main(){
60     //freopen("ddd.in","r",stdin);
61     while(scanf("%d%d",&n,&m)!=EOF){
62         prvs();  s=0,t=n+m+1;
63         int sm=0;
64         for(int i=1;i<=n;++i){
65             a[i]=rd();
66             sm+=a[i];
67             ist(s,i,a[i]);
68         }
69         for(int i=n+1;i<=n+m;++i){
70             a[i]=rd();
71             sm+=a[i];
72             ist(i,t,a[i]);
73         }
74         o=rd();
75         int l,r;
76         while(o --> 0){
77             l=rd(),r=rd();
78             if(l>r)  swap(l,r);
79             ist(l,r,oo);
80         }
81         printf("%d\n",sm-dnc());
82         /*for(int i=s;i<=t;++i){
83             cout<<i<<":"<<endl;
84             for(int j=lk[i];j;j=e[j].nxt)  printf("%d %d\n",e[j].y,e[j].v);
85         }*/
86     }
87     return 0;
88 }
89 
90  
View Code

 

【Codeforces】Orz Panda Cup

原文:https://www.cnblogs.com/cdcq/p/11739066.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!