这是消费税:
你从一个空房间开始,一群n个人在外面等着。在每一步,您可以允许一个人进入房间,或者让一个人进入房间。你能安排一个2 n 步骤的序列,这样每个人的可能组合都可以完成一次吗?
我的解决方案是:
我可以有一个具有 n 元素的位数组。每个元素的状态代表这个人是否在房间里。所以我们完全会在房间内有2个 n 不同的人组合。
该算法可以是标准的回溯,列出所有组合。
我只是想知道我的想法是太天真还是简单?
这个消费税中的任何陷阱?
修改
对于对gray code
的实施感兴趣的人,请参阅
答案 0 :(得分:12)
该算法可以作为标准回溯列出所有组合。
您的解决方案“有效”,但如果天真地实施,则需要大于2个 n 步骤。
请参阅问题陈述中的以下句子:
在每一步中,您可以允许一个人进入房间,或者让一个人离开。
在您的解决方案中,当您列出所有位向量时,您可能会0111
后跟1000
,这意味着三个人将不得不离开房间,而一个人将不得不输入
这需要4个步骤,而不是一个步骤,因此您将获得超过2个 n 步骤来运行所有组合。
然而,可以排列您描述的位向量,使得两个连续向量之间只有一位不同。这就是所谓的Gray code。
以下是维基百科文章的一个例子:
Dec Gray Binary
0 000 000
1 001 001
2 011 010
3 010 011
4 110 100
5 111 101
6 101 110
7 100 111
注意
这意味着您将能够在2个 n 步骤中迭代所有组合。
如何实现这样的序列生成器也在维基百科页面中进行了解释,但如果这是一个练习,我建议你在偷看之前自己尝试;)
答案 1 :(得分:3)
您正在寻找Gray code序列生成器。格雷码序列中的相邻值仅相差一位。
答案 2 :(得分:1)
以下是格雷码序列生成的工作代码
// Binary Reflected Gray Code
void brgc( int *a, int n, int idx, int reflect )
{
if ( n == idx ) {
printIntArr( a, n );
} else {
a[ idx ] = reflect;
brgc( a, n, idx + 1, 0 );
a[ idx ] = !reflect;
brgc( a, n, idx + 1, 1 );
}
}
int main( int argc, char *argv[] )
{
if ( argc != 2 ) {
printf( "Usage...\n" );
return -1;
}
int n = atoi( argv[ 1 ] );
int *a = malloc( sizeof( int ) * n );
brgc( a, n, 0, 0 );
}
答案 3 :(得分:0)
/ package whatever; // don't place package name! /
import java.util.*;
import java.lang.*;
import java.io.*;
/ Name of the class has to be "Main" only if the class is public. /
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
int numberofPeople=3;
int size = 1<<numberofPeople;
for(int i=0;i<size;i++)
{
int num = i^(i>>1);
System.out.println(Integer.toBinaryString(num));
}
}
}