题目描述
将M个白棋子与N个黑棋子排成一行,可以排成多种不同的图案。例如:2个白棋子和2个黑棋子,一共可以排成如下图所示的6种图案(根据组合数计算公式:)
说明: http://10.60.64.213:8080/JudgeOnline/images/4736_2.bmp
请你编写一段程序,输出M个白棋子与N个黑棋子能够组成的所有图案。
为了避免程序输出结果过多导致严重超时,特别限制:1≤M,N≤6
输入
两个正整数M,N表示白棋子与黑棋子的数量,并且满足1≤M,N≤6
输出
M个白棋子与N个黑棋子可以排列的所有图案。
要求:每行输出一种图案,白棋子用0表示,黑棋子用1表示,按升序输出
样例输入 Copy
【测试样例1】
2 1
【测试样例2】
2 2
【测试样例3】
2 3
样例输出 Copy
【测试样例1】
001
010
100
【测试样例2】
0011
0101
0110
1001
1010
1100
【测试样例3】
00111
01011
01101
01110
10011
10101
10110
11001
11010
11100
思路:
就是把0和1组合排列,可以借用二进制转换,统计二进制内1的个数,满足条件就输出
写的比较急,用的方法比较蠢
其实还可以用二进制方法实现排列
代码
#include"bits/stdc++.h"
using namespace std;
string two;
int zh(int number){
two="";
unsigned int mask =1<<31;
int flag=0,num=0;
for(;mask;mask>>=1){
if((number&mask?1:0)==1)
flag=1;
if(flag==1)
two+=number&mask?"1":"0";
}
}
int main(){
int n,m;
cin>>n>>m;
int begin=1,end=0;
for(int i=1;i<m;i++){
begin+=pow(2,i);
}
for(int i=n;i<n+m;i++){
end+=pow(2,i);
}
for(int i=begin;i<=end;i++){
int num1=0;
zh(i);
for(int i=0;i<m+n;i++){
if(two[i]=='1')num1++;
}
if(num1==m){
for(int i=0;i<n+m-two.length();i++){
printf("%c",'0');
}
for(int i=0;i<two.length();i++){
printf("%c",two[i]);
}
printf("\n");
}
}
}