[ICPC-SWERC]2019-2020 ICPC Southwestern European Regional Programming Contest (SWERC 2019-20) D: Gnalcats

【题目链接】:

https://swerc.eu/2019/theme/problems/swerc.pdf

【题意】

7种碱基:C D L P R S U 每个可以对氨基酸链头部进行操作。
L R U 需要链头是二元组,如果不是就fail
给出两串碱基序列,问着两串碱基对一个非常长的氨基酸链操作结果是否相同。
相同:操作都中途fail 或者 完后得到的蛋白质完全相同。

【题解】

用 栈来模拟操作。
用node表示氨基酸,lei=1是简单氨基酸,有一个值num;lei=2是复杂氨基酸,有两个值其他node的编号。
先把足够多的数压入栈,每次操作就是对栈顶元素操作。
用map来查找二元组点,保证lei=2的值相同的在node中只有一个。

ps:一开始没用map,用递归来判断元组值是否相同(递归到最后一层),会超时。
【AC代码】

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<map>
 7 using namespace std;
 8 const int maxn=1e4+7;
 9 typedef pair<int,int> pii;
10 char s[2][maxn];
11 int len[3],tot;
12 struct node{
13     int lei,num,lr,rr;
14 }no[maxn<<3];
15 map<pii,int>ma;
16 int fr[2],st[2][maxn<<3];
17 int work(int x){
18     int v;
19     for(int i=0;i<len[x];i++){
20         v=st[x][fr[x]];
21         if(s[x][i]=='C') st[x][++fr[x]]=v;
22         else if(s[x][i]=='D') fr[x]--;
23         else if(s[x][i]=='S') swap(st[x][fr[x]],st[x][fr[x]-1]);
24         else if(s[x][i]=='L'){
25             if(no[v].lei==2) st[x][fr[x]]=no[v].lr;
26             else return -1;
27         }
28         else if(s[x][i]=='R'){
29             if(no[v].lei==2) st[x][fr[x]]=no[v].rr;
30             else return -1;
31         }
32         else if(s[x][i]=='P'){
33             pii vv=make_pair(v,st[x][fr[x]-1]);
34             if(ma.count(vv)) st[x][--fr[x]]=ma[vv];
35             else{
36                 no[++tot]=(node){2,0,v,st[x][fr[x]-1]};
37                 st[x][--fr[x]]=tot;
38                 ma[vv]=tot;
39             }
40         }
41         else if(s[x][i]=='U'){
42             if(no[v].lei==2){
43                 st[x][fr[x]]=no[v].rr;
44                 st[x][++fr[x]]=no[v].lr;
45             }
46             else return -1;
47         }
48     }
49     return 1;
50 }
51 // bool check(int x,int y){
52 //     if(x==y)return 1;
53 //     if(no[x].lei!=no[y].lei)return 0;
54 //     if(no[x].lei==1){
55 //         if(no[x].num!=no[y].num)return 0;
56 //         else return 1;
57 //     }
58 //     return (check(no[x].lr,no[y].lr)&&check(no[x].rr,no[y].rr));
59 // }//用递归判断相等会超时
60 bool cmp(){
61     if(fr[0]!=fr[1])return 0;
62     for(int i=1;i<=fr[0];i++){
63         if(st[0][i]!=st[1][i])return 0;
64     }
65     return 1;
66 }
67 int main(){
68     scanf("%s",s[0]);
69     scanf("%s",s[1]);
70     len[0]=strlen(s[0]);
71     len[1]=strlen(s[1]);
72     int maa=max(len[0],len[1])*2;    
73     for(int i=1;i<=maa;i++){
74         no[++tot]=(node){1,i,0,0};
75         st[0][++fr[0]]=tot;
76         st[1][++fr[1]]=tot;
77     }
78     int a=work(0),b=work(1);
79     if(a<0&&b<0)printf("True\n");
80     else if(a*b<0)printf("False\n");
81     else{
82         if(cmp())printf("True\n");
83         else printf("False\n");
84     }
85     return 0;
86 }

 

posted @ 2020-08-22 20:59  conver^_^  阅读(362)  评论(0编辑  收藏  举报