脱水缩合(大搜索)
脫水縮合
(merge.c/cpp/pas)
【題目描述】
fqk 退役后開始補習文化課啦, 于是他打開了生物必修一開始復習
蛋白質,他回想起了氨基酸通過脫水縮合生成肽鍵,具體來說,一個
氨基和一個羧基會脫去一個水變成一個肽鍵。于是他腦洞大開,給你
出了這樣一道題:
fqk 將給你 6 種氨基酸和 m 個脫水縮合的規則,氨基酸用
' ' , ' ' , ' ' , ' ' , ' ' , ' ' f e d c b a 表示,每個規則將給出兩個字符串 t s, ,其中
1 | | , 2 | | ? ? t s ,表示 s 代表的兩個氨基酸可以通過脫水縮合變成 t 。然后
請你構建一個長度為 n ,且僅由 ' ' , ' ' , ' ' , ' ' , ' ' , ' ' f e d c b a 構成的氨基酸序列,
如果這個序列的前兩個氨基酸可以進行任意一種脫水縮合, 那么就可
以脫水縮合,脫水縮合后序列的長度將 1 ? ,這樣如果可以進行 1 ? n 次
脫水縮合,最終序列的長度將變為 1 ,我們可以認為這是一個蛋白質,
如果最后的蛋白質為 ' 'a , 那么初始的序列就被稱為一個好的氨基酸序
列。 fqk 想讓你求出有多少好的氨基酸序列。
注:題目描述可能與生物學知識有部分偏差(即氨基酸進行脫水
縮合后應該是肽鏈而不是新的氨基酸),請以題目描述為準。
【輸入格式】
第一行兩個整數 q n, 。
接下來 q 行,每行兩個字符串 t s, ,表示一個脫水縮合的規則。
【輸出格式】
一行,一個整數表示有多少好的氨基酸序列。
【輸入樣例】
3 5
ab a
cc c
ca a
ee c
ff d
【輸出樣例】
4
【樣例解釋】
一共有四種好的氨基酸序列,其脫水縮合過程如下:
"abb" "ab" "a"
"cab" "ab" "a"
"cca" "ca" "a"
"eea" "ca" "a"
【數據范圍】
對于 % 100 的數據, 36 , 6 2 ? ? ? q n 。數據存在梯度。
【時空限制】
對于每個測試點,時間限制為 s 2 ,空間限制為 MB 512 。
?
?
思路:
純搜索題
我們從"a"開始搜索,每次搜到長度等于n的序列就return
不需要判斷這個序列是否合法
因為就是從"a"出來的
這個序列一定合法的
唯一需要判定的就是是否重復
判斷是否重復最好用bfs寫
而且這個題的數據范圍特別小
但是
當時腦抽不知道怎么著就寫了個dfs
按理說dfs是能過的
但是腦子又抽了一下
判斷還放在了return的后面
天啊,50分就這么沒了
要不是這數據水我就爆零了
這告訴我們腦子是個好東西
所以
以后寫搜索一定要先判斷是否重復
?
?
來,上代碼:
(附兩個代碼,一個是dfs(雖然標解就是dfs),另一個是bfs)
dfs:
#include<map> #include<cstdio> #include<string> #include<iostream> #include<algorithm>using namespace std;struct node {string from,to;int next; }; struct node edge[40];int n,q,num;long long int ans=0;string cur,kol;map<char,int>head; map<string,bool>pd;void edge_add(string from,string to) {num++;edge[num].to=to;edge[num].from=from;edge[num].next=head[from[0]];head[from[0]]=num; }void dfs(string kcc,int now) {if(pd[kcc]==true) return ;if(now==n){//cout<<kcc<<endl;ans++;return ;}string kll=kcc;for(int i=head[kcc[kcc.length()-1]];i!=0;i=edge[i].next){string::iterator it=kcc.end()-1;kcc.erase(it);kcc+=edge[i].to;dfs(kcc,now+1);pd[kcc]=true;kcc=kll;} }int main() {scanf("%d%d",&n,&q);n--;for(int i=1;i<=q;i++){cin>>cur>>kol;swap(cur[0],cur[1]);edge_add(kol,cur);}dfs("a",0);cout<<ans<<endl;return 0; }?
bfs:
#include<map> #include<queue> #include<cmath> #include<cstdio> #include<string> #include<iostream>using namespace std;struct node {string from,to;int next; }; struct node edge[1000];int n,q,num;long long int ans=0;string cur,kol;map<char,int>head; map<string,bool>pd;queue<string>que;void edge_add(string from,string to) {num++;edge[num].to=to;edge[num].from=from;edge[num].next=head[from[0]];head[from[0]]=num; }void bfs() {string start="a";que.push(start);pd[start]=true;while(!que.empty()){cur=que.front();for(int i=head[cur[cur.length()-1]];i!=0;i=edge[i].next){kol=que.front();string::iterator it=kol.end()-1;kol.erase(it);kol+=edge[i].to;if(pd[kol]==false){pd[kol]=true;if(kol.length()>=n) ans++;else que.push(kol);}}que.pop();} }int main() {scanf("%d%d",&n,&q);for(int i=1;i<=q;i++){cin>>cur>>kol;swap(cur[0],cur[1]);edge_add(kol,cur);}bfs();cout<<ans<<endl;return 0; }?
轉載于:https://www.cnblogs.com/IUUUUUUUskyyy/p/6048288.html
總結
- 上一篇: Coding and Paper Let
- 下一篇: 从零开始学习编程,会很难学吗?新手想快速