问题描述
给定一个第0天的大小为'm'的二进制字符串100000 ...,对于随后的每一天,每个索引> = 1的更新值由第(i-1)个索引的值的xor给出,第一天的指数。在第n天打印二进制字符串。其中1
写下字符串几天后,我可以看到一些模式,但不能使其简洁。
以下是link
阅读第一个编码回合问题。
解决方法
构造与Pascal三角形相同,因此在第n天,第ith个索引将保持C(n,i)%2,其中C(n,i)是二项式系数。
C(n,i)= n!/(i!(n-i)!)
要弄清楚那是否是偶数,我们只需要知道n!,i!和(n-i)!中2的因数。如果f i>0 && i<n && num2s(n!) > num2s(i!) + num2s((n-i)!)
,则C(n,i)为偶数,C(n,i)%2 = 0
由于您必须花费O(n)时间来计算字符串,因此您最好为所有1到n建立一个num2s(x!)数组。这很容易,因为num2s(x!)= num2s(x)+ num2s((x-1)!)
这是Java的实现:
static String pascalString(int n)
{
int[] num2s = new int[n+2];
//calculate number of 2 factors in 1...n
num2s[0] = num2s[1] = 0;
for (int i=2; i<=n; ++i) {
if ((i&1) == 0) {
num2s[i] = num2s[i/2]+1;
} else {
num2s[i] = 0;
}
}
//convert to number of 2 factors in 1! ... n!
for(int i=2; i<=n; ++i) {
num2s[i] += num2s[i-1];
}
//calculate C(n,i)%2 for all i
StringBuilder sb = new StringBuilder();
for (int i=0; i<=n; ++i) {
if (i > 0 && i < n && num2s[n] > num2s[i] + num2s[n-i]) {
sb.append('0');
} else {
sb.append('1');
}
}
return sb.toString();
}