标签:
题目链接:Shuffle‘m Up
题意:有a和b两个长度为n的字符序列,现定义操作:
将a、b的字符交叉合并到一个序列c,再将c最上面的n个归为a,最下面n个归为b
给出a,b和目标序列c,问最少多少次操作a、b转化为c
解析:将a、b放入哈希表,然后模拟操作过程直接dfs即可。
AC代码:
#include <cstdio> #include <iostream> #include <cstring> #include <map> using namespace std; int n, ans, cnt; string c; map<string, int> sti; bool vis[5010][5010], tg; void dfs(string a, string b, int dep){ if(!sti.count(a)) sti[a] = cnt++; //用map代替哈希表 if(!sti.count(b)) sti[b] = cnt++; if(vis[sti[a]][sti[b]]) return ; vis[sti[a]][sti[b]] = true; string s; for(int i=0; i<n; i++){ //交叉 s.push_back(b[i]); s.push_back(a[i]); } if(s == c){ if(dep < ans) ans = dep; tg = true; return ; } a.clear(); b.clear(); for(int i=0; i<n; i++) a.push_back(s[i]); //上面n个归为a for(int i=n; i<2*n; i++) b.push_back(s[i]); //下面n个归为b dfs(a, b, dep+1); } int main(){ // freopen("in.txt", "r", stdin); int t; scanf("%d", &t); for(int kase=1; kase<=t; kase++){ string a, b; cnt = 0; ans = 0x7ffffff; cin>>n>>a>>b>>c; memset(vis, false, sizeof(vis)); tg = false; sti.clear(); dfs(a, b, 1); printf("%d ", kase); if(tg) printf("%d\n", ans); else puts("-1"); } return 0; }
版权声明:本文为sxk原创文章,转载请附加本文链接^_^
标签:
原文地址:http://blog.csdn.net/u013446688/article/details/47983847