点击打开链接uva 1509
思路:dfs+回溯
分析:
1 给定两个字符串和值k,判断字符串1是否可以映射成字符串2.
2 题目说了一个字符最多可以映射为k个字符,那么我们就不能直接去枚举判断了,所以我们采用搜索的方法,因为每一个字符映射的范围是确定的,那么我们通过搜索和回溯判断即可
代码:
#include<map> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn = 100; char str[maxn] , mapStr[maxn]; map<char , char*>mp; int k , len1 , len2; int dfs(int pos1 , int pos2){ if(pos1 == len1 && pos2 == len2)//最终成立的条件 return 1; if(pos1 == len1 && pos2 != len2)//当pos1 = len1的时候不能在递归了 return 0; if(mp[str[pos1]]){//如果已经有值 char *tmp = mp[str[pos1]]; int len = strlen(tmp); int tmpPos = pos2; for(int i = 0 ; i < len ; i++){ if(tmp[i] != mapStr[tmpPos]) return 0; tmpPos++; } if(dfs(pos1+1 , tmpPos)) return 1; } else{//还没有值 char tmp[maxn]; for(int i = 1 ; i <= k ; i++){ memset(tmp , '\0' , sizeof(tmp)); int pos = 0; for(int j = pos2 ; j < pos2+i ; j++) tmp[pos++] = mapStr[j]; mp[str[pos1]] = tmp; if(dfs(pos1+1 , pos2+i)) return 1; mp[str[pos1]] = 0;//回溯 } } return 0; } int main(){ int Case; scanf("%d" , &Case); while(Case--){ scanf("%d%*c" , &k); gets(str); gets(mapStr); len1 = strlen(str); len2 = strlen(mapStr); mp.clear(); printf("%d\n" , dfs(0 , 0)); } return 0; }