在过去的比赛中,我被要求使用0到9之间的数字生成10位数字符串。字符串中使用的任何四位子字符串都不能再次使用。
使用这些规则可以生成的唯一字符串数量是多少? 列出他们。
示例:的
如果在列表中使用字符串0243697518,则无法生成包含0243,2436,4369,3697,6975,9751和7518的字符串
为了解决这个问题,我编写了一个c ++程序,只需扫描所有的“0123456789”排列,如果之前没有使用过代码的4位子字符串,就将它们添加到解决方案列表中。但我的算法的问题是,解决方案列表的大小取决于您首先添加到列表中的起点。如果我开始从“0123456789”添加到列表中,列表最终会有504个条目,这不是最大要求。我真的很想知道如何解决这个问题,任何帮助都非常感谢。我愿意听你的数学解决方案或任何算法建议来生成所要求的列表。
#include <iostream>
#include <cstdint>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
void main(void)
{
set<string> substring_list; // holds the list of used 4 digit sub-strings
set<string> solution_list;
string code = "0123456789";
do
{
vector<string> subs;
for (int i = 0; i < 7; i++)
{
// adds all 4 digits sub-strings used in the code
subs.push_back(code.substr(i, 4));
}
if ((substring_list.find(subs[0]) == substring_list.end()) &&
(substring_list.find(subs[1]) == substring_list.end()) &&
(substring_list.find(subs[2]) == substring_list.end()) &&
(substring_list.find(subs[3]) == substring_list.end()) &&
(substring_list.find(subs[4]) == substring_list.end()) &&
(substring_list.find(subs[5]) == substring_list.end()) &&
(substring_list.find(subs[6]) == substring_list.end()))
{
// if all substrings are unique and not used before
// then add code into solution list
solution_list.insert(code);
// add newly added code's substrings to substring list.
for (auto s: subs)
{
substring_list.insert(s);
}
}
} while (next_permutation(code.begin(), code.end()));
cout << solution_list.size() << endl;
}