题目链接
重组字符串-腾讯2023笔试(codefun2000)
题目内容
塔子哥是一位喜欢挑战自己的年轻人,他最近在研究字符串的重组问题。他的研究对象是N个小写字母字符串,每个字符串最长只有8个字母。他想设计一个游戏,让自己和朋友们一起玩,看看谁能拼出更多不同的重组字符串。
他决定使用自己的研究成果,计算出所有可能的重组字符串数量。具体地说,他从 每个字符串中选出一个字母,拼成一个新的字符串,同时要求新的字符串不能有重复的字母 。
现在塔子哥想请你来玩一下这个游戏,请问你能拼出多少种不同的重组字符串?
输入描述
第一行输入整数为N
第二行到第N+1行输入N个字符串,全部由小写字母组成
2≤N≤6
1≤len(字符串)≤8
输出描述
输出一个整数,代表总共能组成多少个重组字符串
样例1
输入
5
abca
acds
aca
vac
bba
输出
6
提示
暴力搜索+剪枝
题解1
#include<bits/stdc++.h>
using namespace std;
int n;
set<vector<char>> res;
vector<char> now_res;
string s[10];
bool vis[30];
void dfs(int x){
if(int(now_res.size()) < x) return; // 需要保证从每个字符串中选取一个字符
if(x == n){
res.insert(now_res); // 将当前的选取方案放入集合,如果之前存在这种选取方案,则res.size()不变,否则res.size()+1
return;
}
for(int i = x + 1; i <= n; i++){
for(int j = 0; j < int(s[i].size()); j++){
if(!vis[s[i][j] - 'a'] && (j == 0 || s[i][j] != s[i][j - 1])){ // 保证从每个字符串中的选取的字符中,没有重复字符
now_res.push_back(s[i][j]);
vis[s[i][j] - 'a'] = 1;
dfs(i);
now_res.pop_back();
vis[s[i][j] - 'a'] = 0;
}
}
}
}
int main(){
cin>>n;
for(int i = 1; i <= n; i++){
cin>> s[i];
sort(s[i].begin(), s[i].end()); // 保证同一个字符串重复的字符放在相邻位置
}
dfs(0);
cout<<res.size()<<'\n';
return 0;
}