脱水缩合(大搜索)
脫水縮合
(merge.c/cpp/pas)
【題目描述】
fqk 退役后開始補(bǔ)習(xí)文化課啦, 于是他打開了生物必修一開始復(fù)習(xí)
蛋白質(zhì),他回想起了氨基酸通過脫水縮合生成肽鍵,具體來說,一個(gè)
氨基和一個(gè)羧基會(huì)脫去一個(gè)水變成一個(gè)肽鍵。于是他腦洞大開,給你
出了這樣一道題:
fqk 將給你 6 種氨基酸和 m 個(gè)脫水縮合的規(guī)則,氨基酸用
' ' , ' ' , ' ' , ' ' , ' ' , ' ' f e d c b a 表示,每個(gè)規(guī)則將給出兩個(gè)字符串 t s, ,其中
1 | | , 2 | | ? ? t s ,表示 s 代表的兩個(gè)氨基酸可以通過脫水縮合變成 t 。然后
請(qǐng)你構(gòu)建一個(gè)長(zhǎng)度為 n ,且僅由 ' ' , ' ' , ' ' , ' ' , ' ' , ' ' f e d c b a 構(gòu)成的氨基酸序列,
如果這個(gè)序列的前兩個(gè)氨基酸可以進(jìn)行任意一種脫水縮合, 那么就可
以脫水縮合,脫水縮合后序列的長(zhǎng)度將 1 ? ,這樣如果可以進(jìn)行 1 ? n 次
脫水縮合,最終序列的長(zhǎng)度將變?yōu)?1 ,我們可以認(rèn)為這是一個(gè)蛋白質(zhì),
如果最后的蛋白質(zhì)為 ' 'a , 那么初始的序列就被稱為一個(gè)好的氨基酸序
列。 fqk 想讓你求出有多少好的氨基酸序列。
注:題目描述可能與生物學(xué)知識(shí)有部分偏差(即氨基酸進(jìn)行脫水
縮合后應(yīng)該是肽鏈而不是新的氨基酸),請(qǐng)以題目描述為準(zhǔn)。
【輸入格式】
第一行兩個(gè)整數(shù) q n, 。
接下來 q 行,每行兩個(gè)字符串 t s, ,表示一個(gè)脫水縮合的規(guī)則。
【輸出格式】
一行,一個(gè)整數(shù)表示有多少好的氨基酸序列。
【輸入樣例】
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"
【數(shù)據(jù)范圍】
對(duì)于 % 100 的數(shù)據(jù), 36 , 6 2 ? ? ? q n 。數(shù)據(jù)存在梯度。
【時(shí)空限制】
對(duì)于每個(gè)測(cè)試點(diǎn),時(shí)間限制為 s 2 ,空間限制為 MB 512 。
?
?
思路:
純搜索題
我們從"a"開始搜索,每次搜到長(zhǎng)度等于n的序列就return
不需要判斷這個(gè)序列是否合法
因?yàn)榫褪菑?#34;a"出來的
這個(gè)序列一定合法的
唯一需要判定的就是是否重復(fù)
判斷是否重復(fù)最好用bfs寫
而且這個(gè)題的數(shù)據(jù)范圍特別小
但是
當(dāng)時(shí)腦抽不知道怎么著就寫了個(gè)dfs
按理說dfs是能過的
但是腦子又抽了一下
判斷還放在了return的后面
天啊,50分就這么沒了
要不是這數(shù)據(jù)水我就爆零了
這告訴我們腦子是個(gè)好東西
所以
以后寫搜索一定要先判斷是否重復(fù)
?
?
來,上代碼:
(附兩個(gè)代碼,一個(gè)是dfs(雖然標(biāo)解就是dfs),另一個(gè)是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; }?
轉(zhuǎn)載于:https://www.cnblogs.com/IUUUUUUUskyyy/p/6048288.html
總結(jié)
- 上一篇: Coding and Paper Let
- 下一篇: 从零开始学习编程,会很难学吗?新手想快速