「NOIP2002」「Codevs1099」 字串變換
阿新 • • 發佈:2018-09-26
但是 字母 下標 ref desc 相關 put -c 系列
$‘abc’->‘xu’ ‘ud’->‘y’ ‘y’->‘yz’$
則此時,$A$ 可以經過一系列的變換變為 $B$,其變換的過程為:
$‘abcd’->‘xud’->‘xy’->‘xyz’$
共進行了三次變換,使得 $A$ 變換為$B$。 輸入描述 Input Description
樣例輸入
Sample Input
1099 字串變換
2002年NOIP全國聯賽提高組
時間限制: 1 s 空間限制: 128000 KB 題目等級 : 黃金 Gold 題目描述 Description已知有兩個字串 $A$, $B$ 及一組字串變換的規則(至多6個規則):
$A1$ -> $B1$
$A2$ -> $B2$
規則的含義為:在$ A$中的子串 $A1$ 可以變換為 $B1$、$A2$ 可以變換為 $B2$ …。
例如:$A=‘abcd‘ B=‘xyz‘$
變換規則為:
則此時,$A$ 可以經過一系列的變換變為 $B$,其變換的過程為:
$‘abcd’->‘xud’->‘xy’->‘xyz’$
共進行了三次變換,使得 $A$ 變換為$B$。 輸入描述 Input Description
輸入格式如下:
$A$ $B$
$A1$ $B1$ \
$A2$ $B2$ |-> 變換規則
... ... /
所有字符串長度的上限為 20。
若在 10 步(包含 10步)以內能將 $A$ 變換為 $B$ ,則輸出最少的變換步數;否則輸出"NO ANSWER!"
abcd xyz
abc xu
ud y
y yz
3
數據範圍及提示 Data Size & Hinthehe
題解
教材(來自Luogu的題解
這種字符串變換都是考STL的使用啊!!!QAQ
前置知識:
1.map入門:
定義: map<type1,type2>mp; 相當於一個用type1當下標的數組。 eg: map<double,int>mp; mp[2.6]=3; cout<<mp[2.6]; //輸出3 查找: 直接向數組一樣訪問就行了,但是要先問一下是否存在。 if(mp.find(x)==mp.end())表示這個下標沒有存過。 然後map的各種操作應該(應該?)都是O(log)的。
2.string相關:
定義: string a; //可以定義字符串數組 訪問其中下標為i的字母: int k=a[i]; //註意是從0開始排的 在string a裏面找子串b int pos=a.find(b); //如果存在子串b 返回b的第一個字符對應在a裏面的下標(若有多個匹配,返回第一個匹配的下標) 否則返回-1 (劃重點) 把string a從pos開始長l的字符整體換成字串b a.replace(pos,l+1,b); //stl的區間都是左開右閉的
然後就可以亂搞了,BFS一下就星。
這個st.replace可以再神奇一點嗎?!!!!!
1 /* 2 qwerta 3 P1032 字串變換 4 Accepted 5 100 6 代碼 C++,1.14KB 7 提交時間 2018-09-26 19:13:29 8 耗時/內存 9 26ms, 1432KB 10 */ 11 #include<iostream> 12 #include<cstring> 13 #include<cstdio> 14 #include<queue> 15 #include<map> 16 using namespace std; 17 string a[13],b[13]; 18 string ma,mb; 19 queue<string>qs;//存字符串 20 queue<int>qn;//存對應的轉換次數 21 int n=1; 22 map<string,int>m; 23 int bfs() 24 { 25 qs.push(ma);//push初始狀態 26 qn.push(0); 27 while(!qs.empty()&&qn.front()<10)//如果有的搜並且次數不超過10 28 { 29 int d=qn.front(); 30 string s=qs.front(); 31 if(m.find(s)==m.end())//如果s在map中沒有被記錄過 32 { 33 m[s]=1;//mark一下 34 for(int c=1;c<=n;++c)//枚舉六種變換 35 { 36 s=qs.front(); 37 while((s.find(a[c]))!=-1)//如果找得到子串a[c] 38 { 39 string ss=qs.front();//搞一個輔助的ss 40 int pos=s.find(a[c]); 41 ss.replace(pos,a[c].size(),b[c]);//把ss替換一下 42 if(ss==mb)return d+1;//找到了就return 43 qs.push(ss); 44 qn.push(d+1);//push當前的收獲 45 s[pos]=‘*‘;//把s的這一位換成無關字符,這樣下一次就會自動搜下一位了 46 } 47 } 48 } 49 qs.pop();qn.pop(); 50 } 51 return -1;//搜完了還沒搜到則無解 52 } 53 int main() 54 { 55 //freopen("a.in","r",stdin); 56 ios::sync_with_stdio(false); 57 cin.tie(false),cout.tie(false);//cin好伴侶(據說能快過scanf 58 cin>>ma>>mb; 59 while(cin>>a[n]>>b[n])n++; 60 n--; 61 int k=bfs(); 62 if(k==-1){cout<<"NO ANSWER!";} 63 else cout<<k; 64 return 0; 65 }
不用map判重也不會TLE 差評
不用map: /* qwerta P1032 字串變換 Accepted 100 代碼 C++,1.14KB 提交時間 2018-09-26 19:14:03 耗時/內存 389ms, 64472KB */ //(摔
「NOIP2002」「Codevs1099」 字串變換