题目描述:
有一个考古学家发现一个石碑,但是很可惜,发现时其已经断成多段,原地发现n个断口整齐的石碑碎片。为了破解石碑内容,考古学家希望有程序能帮忙计算复原后的石碑文字组合数,你能帮忙吗?
输入描述:
第一行输入 n,表示石碑碎片的个数;
第二行依次输入石碑碎片上的文字内容s,共有n组;
输出描述:
输出石碑文字的组合(按照升序排列),行末无多余空格。
备注:如果存在石碑碎片内容完全相同,则由于碎片间的顺序变换不影响复原后的碑文内容,即相同碎片间的位置变换不影响组合。
用例1:
输入
3
a b c
输出
abc
acb
bac
bca
cab
cba
说明:当石碑片上内容为'a','b','c'时,则组合有abc,acb,bac,bca,cab,cba
用例2:
输入
3
a a b
输出
aab
aba
baa
说明:当石碑片上内容为'a','a','b'时,则组合有aab,aba,baa
用例3:
输入
3
a b ab
输出
aabb
abab
abba
baab
baba
说明:当石碑片上内容为'a','b','ab'时,则组合有aabb,abab,abba,baab,baba
C++源码:
#include <iostream>
#include <vector>
#include <string>
#include <set>
#include <algorithm>
#include <cstdlib>
#include <sstream>
using namespace std;
void allList(vector<string>& textList, string h, vector<string>& res) {
if (textList.empty()) {
res.push_back(h);
return;
}
else {
int listLen = textList.size();
for (int i = 0; i < listLen; ++i) {
string temp1 = textList[i];
vector<string> temp2(textList);
temp2.erase(temp2.begin() + i);
allList(temp2, h + temp1, res);
}
}
}
int main() {
while (true) {
int n;
cin >> n;
if (cin.fail()) { // 简单检查输入是否有效
cin.clear(); // 清除错误标志
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 忽略错误输入直到下一个换行符
continue; // 跳过这次循环重新开始
}
string s;
getline(cin, s); // 跳过空白行
getline(cin, s);
vector<string> textList;
stringstream ss(s);
string item;
while (getline(ss, item, ' ')) {
textList.push_back(item);
}
vector<string> tempResult;
string h = "";
allList(textList, h, tempResult);
set<string> uniqueRes(tempResult.begin(), tempResult.end());
vector<string> result(uniqueRes.begin(), uniqueRes.end());
sort(result.begin(), result.end());
for (const auto& i : result) {
cout << i << endl;
}
break;
}
system("pause");
return 0;
}