AcWing 92.指数型枚举 狗妈的粉丝

 

狗妈的粉丝喜欢想屁吃,后来他们发现桃子peach和屁吃发音一样所以所有人都喜欢吃桃子。

现在有n个桃子,编号从1到n

要把所有的桃子的枚举结果列出来供DD们吃。

而且第一个数尽量大,第一个数尽量大基础上,数尽量少,数的数目相同就数的数值就尽量大。什么都不输出最大。

DD们已经快饿的不行了,聪明的你能帮帮他们吗?

 

样例输入

3

样例输出

 

3

2 3

1

1 3

1 2

1 2 3

 

其实这个比较简单的就是递归的方法去做,先不选,后选的DFS就能得到这个结果。

import java.util.Scanner;

public class Main {
	static boolean flag[] = new boolean[20];
	static int n;
	static void dfs(int x){
		if(x == n){
			for (int i = 0; i < n; i++) {
				if(flag[i] == true){
					System.out.print((i+1)+" ");
				}
			}
			System.out.println();
			return;
		}
		flag[x] = false;
		dfs(x+1);
		flag[x] = true;
		dfs(x+1);
		return;
	}
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		n = scanner.nextInt();
		dfs(0);
	}
}

为了节省数组空间,其实这个问题开一个bool数组是没有必要的。可以用位运算解决数组的问题

位运算就是二进制上每一位上的代表这个位置是否被选择,

u | 1<<x 选择第X位置的数字。

    int tt = u >> i & 1;  第i个位置被选中,u 往 右移动了i个位置那么 最低位就是i这个数值。和1 相与,是1就是1,是0 就是 0;

不过提交姬竟然比数组还慢,不知道为什么咧。

public class Main {
	static boolean flag[] = new boolean[20];
	static int n;
	static void dfs(int x,int u){
		if(x == n){
			for (int i = 0; i < n; i++) {
				int tt = u >> i & 1;
				if(tt != 0){
					System.out.print((i+1)+" ");
				}
			}
			System.out.println();
			return;
		}

		dfs(x+1,u);

		dfs(x+1,u|1<<x);
		return;
	}
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		n = scanner.nextInt();
		dfs(0,0);
	}
}

最后可以把递归改成递推,直接枚举所有可能 然后倒着输出就可以了,因为正好是一直增加的数反过来,是不是很神奇?

import java.util.Scanner;

public class Zhishumeijv3 {
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int n;
		Scanner scanner = new Scanner(System.in);
		n = scanner.nextInt();
		for (int i = 0; i <  1 << n; i++) {
			for (int j = n-1; j >= 0 ; j--) {
				int tt =i >> j & 1; 
				if( tt != 0)
					System.out.print((n+1-(j+1))+" ");
			}
			System.out.println();
		}
	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值