UVa 1509 - Leet(MAP + DFS)

题意

给一串字符串,和一个对应的Leet,问能否存在一个转化使其相等。

其中,一个字符只能对应一种Leet,而一种Leet可以对应多个字符。

也就是说,这样是可以的

abc 
sss

思路

因为l <= 15, k <= 3,考虑暴力枚举。

对原字符串逐个位置进行枚举对应的Leet和DFS,并用map存储。

如果该字符之前出现过,判断存储的Leet是否和接下来的Leet相等,相等,继续。不相等返回。

第一次用string写,2400+ms,吓cry。

优化了一下,1600+ms。

用char写,600+ms

代码

string版

 
 
  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <functional>
  4. #include <stack>
  5. #include <set>
  6. #include <cctype>
  7. #include <cstdlib>
  8. #include <iostream>
  9. #include <string>
  10. #include <vector>
  11. #include <queue>
  12. #include <cstring>
  13. #include <string>
  14. #include <sstream>
  15. #include <map>
  16. #include <cmath>
  17. #define LL long long
  18. #define lowbit(x) ((x) & (-x))
  19. #define MP(a, b) make_pair(a, b)
  20. #define MS(arr, num) memset(arr, num, sizeof(arr))
  21. #define PB push_back
  22. #define ROP freopen("input.txt", "r", stdin);
  23. const double PI = acos(-1.0);
  24. const int INF = 0x3f3f3f3f;
  25. using namespace std;
  26. const int MAXN = (1 << 16) + 5;
  27. typedef pair<int, int> pii;
  28. typedef vector<int>::iterator viti;
  29. typedef vector<pii>::iterator vitii;
  30. map<char, string> mp;
  31. string str, dic;
  32. int k;
  33. bool DFS(int curPos, int start)
  34. {
  35. if (curPos == str.length())
  36. {
  37. if (dic.size() == start) return true; //必须同时到达最后,否则不相等。
  38. else return false;
  39. }
  40. if (start >= dic.size()) return false; //枚举多了
  41. if (mp.count(str[curPos])) //如果之前已经存在
  42. {
  43. string ans = mp[str[curPos]];
  44. if (dic.substr(start, ans.size()) != ans) return false;
  45. if (DFS(curPos + 1, start + ans.size())) return true;
  46. }
  47. else
  48. {
  49. for (int i = 1; i <= k && start + i <= dic.size(); i++)
  50. {
  51. string tmp = dic.substr(start, i); //枚举对应的leet
  52. mp[str[curPos]] = tmp;
  53. if (DFS(curPos + 1, start + i)) return true;
  54. mp.erase(str[curPos]); //一定要消除。不然等到回去的时候本来不应该存在的就存在了
  55. }
  56. }
  57. return false;
  58. }
  59. int main()
  60. {
  61. ios::sync_with_stdio(false);
  62. //ROP;
  63. int T, i, j, n;
  64. cin >> T;
  65. while (T--)
  66. {
  67. cin >> k;
  68. cin >> str >> dic;
  69. if (str.size() * 3 < dic.size())
  70. {
  71. cout << "0" << endl;
  72. continue;
  73. }
  74. bool flag = false;
  75. mp.clear();
  76. if (!DFS(0, 0)) cout << "0" << endl;
  77. else cout << "1" << endl;
  78. }
  79. return 0;
  80. }

char版

 
 
  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <functional>
  4. #include <stack>
  5. #include <set>
  6. #include <cctype>
  7. #include <cstdlib>
  8. #include <iostream>
  9. #include <string>
  10. #include <vector>
  11. #include <queue>
  12. #include <cstring>
  13. #include <string>
  14. #include <sstream>
  15. #include <map>
  16. #include <cmath>
  17. #define LL long long
  18. #define lowbit(x) ((x) & (-x))
  19. #define MP(a, b) make_pair(a, b)
  20. #define MS(arr, num) memset(arr, num, sizeof(arr))
  21. #define PB push_back
  22. #define ROP freopen("input.txt", "r", stdin);
  23. const double PI = acos(-1.0);
  24. const int INF = 0x3f3f3f3f;
  25. using namespace std;
  26. const int MAXN = 30 + 5;
  27. typedef pair<int, int> pii;
  28. typedef vector<int>::iterator viti;
  29. typedef vector<pii>::iterator vitii;
  30. map<char, char *> mp;
  31. char str[MAXN], dir[MAXN];
  32. int k;
  33. bool DFS(int curPos, int start)
  34. {
  35. if (curPos == strlen(str))
  36. {
  37. if (strlen(dir) == start) return true;
  38. else return false;
  39. }
  40. if (start >= strlen(dir)) return false;
  41. if (mp[str[curPos]])
  42. {
  43. char *tmp = mp[str[curPos]];
  44. int len = strlen(tmp);
  45. int tmpPos = start;
  46. for (int i = 0; i < len; i++)
  47. {
  48. if (tmp[i] != dir[tmpPos]) return false;
  49. tmpPos++;
  50. }
  51. if (DFS(curPos + 1, tmpPos)) return true;
  52. }
  53. else
  54. {
  55. char tmp[MAXN];
  56. for (int i = 1; i <= k; i++)
  57. {
  58. MS(tmp, 0);
  59. int pos = 0;
  60. for (int j = start; j < start + i; j++)
  61. tmp[pos++] = dir[j];
  62. mp[str[curPos]] = tmp;
  63. if (DFS(curPos + 1, start + i)) return true;
  64. mp[str[curPos]] = 0;
  65. }
  66. }
  67. return false;
  68. }
  69. int main()
  70. {
  71. ios::sync_with_stdio(false);
  72. //ROP;
  73. int T, i, j, n;
  74. cin >> T;
  75. while (T--)
  76. {
  77. cin >> k;
  78. cin >> str >> dir;
  79. if (strlen(str) * 3 < strlen(dir))
  80. {
  81. cout << "0" << endl;
  82. continue;
  83. }
  84. mp.clear();
  85. if (!DFS(0, 0)) cout << "0" << endl;
  86. else cout << "1" << endl;
  87. }
  88. return 0;
  89. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值