算法竞赛入门经典:第七章 暴力求解法 7.9位向量法

/*
位向量法:
构造一个位向量B[i],而不是直接构造子集A本身,其中B[i] = 1当且仅当i在子集A中。
注意:此题不是求排列,而是求子集,这里n个元素有2^n-1个子集,因为空集无法打印出来

输入:
3
输出:
0 1 2
0 1
0 2
0
1 2
1
2
*/

/*
关键:
1 if(pos == n)//凡是递归,先写递归出口,否则若写在后面,很容易漏掉,所有元素是否选择确定完毕后才是一个完整的子集,因此是if(pos == n)才输出
2 			if(iArr[i])//确保i在子集iArr中
			{
				//printf("%d ",iArr[i]);//打印当前值集合
				printf("%d ",i);
			}
			printf("\n");//别忘了打印换行
3 return ;//如果这里不返回,那么pos会一直大于n,走下去
4 	iArr[pos] = 1;//将当前元素放进去,0 1 2.解答树上是2^n-1个节点,因为不分解(不完整的解)也是解答树上的节点
	printPermutation(n,iArr,pos+1);
	iArr[pos] = 0;//将当前元素取出,0 1
	printPermutation(n,iArr,pos+1);
*/

#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 1024

void printPermutation(int n,int *iArr,int pos)
{
	if(pos == n)//凡是递归,先写递归出口,否则若写在后面,很容易漏掉,所有元素是否选择确定完毕后才是一个完整的子集,因此是if(pos == n)才输出
	{
		for(int i = 0 ;  i < n; i++)
		{
			if(iArr[i])//确保i在子集iArr中
			{
				//printf("%d ",iArr[i]);//打印当前值集合
				printf("%d ",i);
			}
		}
		printf("\n");//别忘了打印换行
		return ;//如果这里不返回,那么pos会一直大于n,走下去
	}
	iArr[pos] = 1;//将当前元素放进去,0 1 2.解答树上是2^n-1个节点,因为不分解(不完整的解)也是解答树上的节点
	printPermutation(n,iArr,pos+1);
	iArr[pos] = 0;//将当前元素取出,0 1
	printPermutation(n,iArr,pos+1);
}

int main(int argc,char* argv[])
{
	int n;
	scanf("%d",&n);
	int iArr[MAXSIZE];
	printPermutation(n,iArr,0);
	system("pause");
	return 0;
}

你可能感兴趣的:(算法竞赛)