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. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
探险家小扣的行动轨迹,都将保存在记录仪中。expeditions[i] 表示小扣第 i 次探险记录,用一个字符串数组表示。其中的每个「营地」由大小写字母组成,通过子串 -> 连接。例:"Leet->code->Campsite",表示到访了 "Leet"、"code"、"Campsite" 三个营地。expeditions[0] 包含了初始小扣已知的所有营地;对于之后的第 i 次探险(即 expeditions[i] 且 i > 0),如果记录中包含了之前均没出现的营地,则表示小扣 新发现 的营地。 请你找出小扣发现新营地最多且索引最小的那次探险,并返回对应的记录索引。如果所有探险记录都没有发现新的营地,返回 -1。注意: 大小写不同的营地视为不同的营地; 营地的名称长度均大于 0。用python实现。给你几个例子:示例 1: 输入:expeditions = ["leet->code","leet->code->Campsite->Leet","leet->code->leet->courier"] 输出:1 解释: 初始已知的所有营地为 "leet" 和 "code" 第 1 次,到访了 "leet"、"code"、"Campsite"、"Leet",新发现营地 2 处:"Campsite"、"Leet" 第 2 次,到访了 "leet"、"code"、"courier",新发现营地 1 处:"courier" 第 1 次探险发现的新营地数量最多,因此返回 1。示例 2: 输入:expeditions = ["Alice->Dex","","Dex"] 输出:-1 解释: 初始已知的所有营地为 "Alice" 和 "Dex" 第 1 次,未到访任何营地; 第 2 次,到访了 "Dex",未新发现营地; 因为两次探险均未发现新的营地,返回 -1
04-23
我的理解是,你想让我编写一段 Python 代码,实现一个算法,用于在给定的探险记录中找到发现新营地最多且索引最小的探险记录。 那么首先,我需要解析题目中的输入输出要求。 输入要求: - expeditions:一个字符串数组,表示小扣第一次到访的所有营地,和之后的每次探险记录(一个记录就是一个字符串,其中营地通过子串 -> 连接)。 输出要求: - 如果所有的探险记录都没有发现新的营地,则返回 -1; - 否则,返回发现新营地最多且索引最小的探险记录的索引。注:探险记录的索引从 0 开始计数。 接下来,我可以考虑如何编写代码来解决这个问题。 我的思路是,首先用一个集合记录所有已知的营地名称,然后遍历每个探险记录,依次将其中的营地名称加入到集合中,并判断是否有新的营地被发现。 如果某个探险记录中发现了新的营地,那么我就记录下发现了多少个新营地,以及这个探险记录的索引。最后,遍历所有的探险记录,找到发现新营地最多且索引最小的记录。 代码如下: ```python def find_new_camp(expeditions): known_camps = set() # 已知的营地集合 max_new_camps = 0 # 最多的新营地数量 max_new_camps_index = -1 # 最多新营地数量的探险记录的索引 for i in range(len(expeditions)): sub_camps = expeditions[i].split("->") # 提取探险记录中所有的营地名称 num_new_camps = 0 # 记录这个探险记录发现的新营地数量 for camp in sub_camps: if camp not in known_camps: # 如果这个营地是新的,就记录一下 known_camps.add(camp) num_new_camps += 1 if num_new_camps > max_new_camps: # 如果发现了更多的新营地,就更新最大值和索引 max_new_camps = num_new_camps max_new_camps_index = i return max_new_camps_index if max_new_camps > 0 else -1 ``` 我使用了两个变量 `max_new_camps` 和 `max_new_camps_index` 来记录已经遍历过的探险记录中,发现了最多的新营地数量,以及具有最多新营地数量的探险记录的索引。然后我遍历所有的探险记录,统计其中发现的新营地数量,如果大于当前的最大值,就更新 `max_new_camps` 和 `max_new_camps_index` 变量。最后,如果发现了新的营地,就返回 `max_new_camps_index`。如果所有的探险记录都没有发现新营地,就返回 -1。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值