这是消费税:
你从一个空房间开始,一群 n 人在外面等着。在每一步,您可以允许一个人进入房间,也可以让一个人出去。你能安排一个 2 n步的序列,使得每个可能的人组合都只实现一次吗?
我的解决方案是:
我可以有一个包含n 个元素的位数组。每个元素的状态代表此人是否在房间内。因此,我们总共将在房间里有 2 n 个不同的人组合。
该算法可以是列出所有组合的标准回溯。
我只是想知道我的想法是太天真还是太简单了?
这个消费税有什么陷阱吗?
编辑:
对于有兴趣实施的人gray code,请参阅
这是消费税:
你从一个空房间开始,一群 n 人在外面等着。在每一步,您可以允许一个人进入房间,也可以让一个人出去。你能安排一个 2 n步的序列,使得每个可能的人组合都只实现一次吗?
我的解决方案是:
我可以有一个包含n 个元素的位数组。每个元素的状态代表此人是否在房间内。因此,我们总共将在房间里有 2 n 个不同的人组合。
该算法可以是列出所有组合的标准回溯。
我只是想知道我的想法是太天真还是太简单了?
这个消费税有什么陷阱吗?
编辑:
对于有兴趣实施的人gray code,请参阅
该算法可以是列出所有组合的标准回溯。
您的解决方案“有效”,但如果实施得天真,它将需要超过 2 n 个步骤。
请参阅问题陈述中的以下句子:
在每一步,您可以允许一个人进入房间,也可以让一个人出去。
在您的解决方案中,当您列出所有位向量时,您可能会0111遵循1000这意味着三个人必须离开房间,一个人必须进入。
这需要 4 个步骤,而不是一个,因此您将获得超过 2 n 个步骤来运行所有组合。
但是,您可以排列您描述的位向量,使得两个连续向量之间只有一位不同。这就是所谓的格雷码。
这是维基百科文章中的一个示例:
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步迭代所有组合。
如何实现这样的序列生成器在 Wikipedia 页面中也有说明,但如果是练习,我建议你在偷看之前自己尝试一下;)
您正在寻找格雷码序列生成器。格雷码序列中的相邻值仅相差一位。
这是格雷码序列生成的工作代码
// 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 );
}
/ 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));
}
}
}