全排列问题(51nod-1384)
问题来源:51nod
字符串S(包含0-9,可能有重复的字符),按照字典序从小到大,输出S包括的字符组成的所有排列。
回溯问题,本质是DFS问题。
首先统计字符串中各个字符的出现次数,存入数组cnt[10],然后进行深度搜索。
深度搜索的规则为对于第i位,按照字典序0-9,如果cnt[k]不为0,则cnt[k]- -,进行第i+1位的搜索,回溯回来需要cnt[k]++恢复原样。
#include <iostream>
#include <string>
#define FOR(n, a, b) for(int n = a; n < b; ++n)
#define FOR_iter(n, c) for(auto n = c.begin(); n != c.end(); ++n)
using namespace std;
void DFS(int* cnt, int l, string head)
{
if (l == 1)
{
FOR(i, 0, 10)
if (cnt[i] != 0)
cout << head + static_cast<char>(i + '0') << endl;
}
else
{
FOR(i, 0, 10)
{
if (cnt[i] != 0)
{
cnt[i]--;
DFS(cnt, l - 1, head + static_cast<char>(i + '0'));
cnt[i]++;
}
}
}
}
int main()
{
string s;
int cnt[10] = { 0 };
cin >> s;
FOR_iter(n, s)
cnt[*n - '0'] ++;
DFS(cnt, s.length(), "");
return 0;
}