思路:数组中有H个1, N-H个0,按照字典序全排列,注意这里数组可以开int型的也可以开char型的,char型的在这里感觉用起来更方便,至少不要for循环,用char型的数组记得要初始化(memset),或者s[N] = '\0',因为这里有多组数据。
AC代码①:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int a[20];
int T;
int N, H;
int main() {
scanf("%d", &T);
while(T--) {
cin >> N >> H;
for(int i = 0 ; i < N - H; i++) a[i] = 0;
for(int i = N - H; i < N; i++) a[i] = 1;
do
{
for(int i = 0; i < N; i++) printf("%d", a[i]);
printf("\n");
}while(next_permutation(a, a + N));
if(T) printf("\n");
}
return 0;
}
AC代码②:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
char a[20];
int T;
int N, H;
int main() {
scanf("%d", &T);
while(T--) {
cin >> N >> H;
for(int i = 0 ; i < N - H; i++) a[i] = '0';
for(int i = N - H; i < N; i++) a[i] = '1';
a[N] = '\0';
do
{
printf("%s\n", a);
}while(next_permutation(a, a + N));
if(T) printf("\n");
}
return 0;
}
AC代码③(不调用库函数的生成可重集的排列):
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
char s[20], str[20];
void print_permutation(char *s, char *str, int len, int cur) {
if(cur == len) printf("%s\n", str);
else for(int i = 0; i < len; i++) {
if(!i || s[i] != s[i - 1]) {
int c1 = 0, c2 = 0;
for(int j = 0; j < len; j++) if(s[i] == s[j]) c1 ++;
for(int j = 0; j < cur; j++) if(s[i] == str[j]) c2 ++;
if(c2 < c1) {
str[cur] = s[i];
print_permutation(s, str, len, cur + 1);
}
}
}
}
int main() {
int T;
cin >> T;
while(T) {
int N, H;
scanf("%d %d", &N, &H);
memset(s, 0, sizeof(s));
for(int i = 0; i < N - H; i++) s[i] = '0';
for(int i = N - H; i < N; i++) s[i] = '1';
memset(str, 0, sizeof(str));
print_permutation(s, str, N, 0);
if(T) printf("\n" );
}
return 0;
}