我有以下问题:
点(a)很简单,这是我的解决方案:
#include <stdio.h>
#include <string.h>
#define MAX_DIGITS 1000000
char conjugateDigit(char digit)
{
if(digit == '1')
return '2';
else
return '1';
}
void conjugateChunk(char* chunk, char* result, int size)
{
int i = 0;
for(; i < size; ++i)
{
result[i] = conjugateDigit(chunk[i]);
}
result[i] = '\0';
}
void displaySequence(int n)
{
// +1 for '\0'
char result[MAX_DIGITS + 1];
// In this variable I store temporally the conjugates at each iteration.
// Since every component of the sequence is 1/4 the size of the sequence
// the length of `tmp` will be MAX_DIGITS / 4 + the string terminator.
char tmp[(MAX_DIGITS / 4) + 1];
// There I assing the basic value to the sequence
strcpy(result, "1221");
// The initial value of k will be 4, since the base sequence has ethe length
// 4. We can see that at each step the size of the sequence 4 times bigger
// than the previous one.
for(int k = 4; k < n; k *= 4)
{
// We conjugate the first part of the sequence.
conjugateChunk(result, tmp, k);
// We will concatenate the conjugate 2 time to the original sequence
strcat(result, tmp);
strcat(result, tmp);
// Now we conjugate the conjugate in order to get the first part.
conjugateChunk(tmp, tmp, k);
strcat(result, tmp);
}
for(int i = 0; i < n; ++i)
{
printf("%c", result[i]);
}
printf("\n");
}
int main()
{
int n;
printf("Insert n: ");
scanf("%d", &n);
printf("The result is: ");
displaySequence(n);
return 0;
}
但是对于b点,我必须以对数时间生成n
个数字。我不知道该怎么做。我试图找到该序列的数学属性,但我失败了。你能帮我吗?解决方案本身并不重要,但如何在短时间内解决这类问题。
这problem去年(2014年)在布加勒斯特大学数学与计算机科学系的入学考试中获得。
答案 0 :(得分:1)
有一个简单的编程解决方案,关键是使用递归。
首先确定k
的长度超过s_k
的最小n
,以便在n
中存在s_k
个数字。根据定义,s_k
可以分成4个等长部分。您可以轻松确定第n
个符号落入哪个部分,该部分中n
个符号的数量是多少---请说明n
- 符号整个字符串是n'
- 在这一部分内。这部分是s_{k-1}
,inv(s_{k-1})
。在任何情况下,你递归地确定n'
中的s_{k-1}
符号是什么,然后,如果需要,将其反转。
答案 1 :(得分:1)
假设您将 d_ij 定义为 s_j 中 i 数字的值。
请注意,对于固定的 i , d_ij 仅针对足够大的 j 值定义(首先, s_j < / em>不够大。)
现在你应该能够向自己证明以下两点:
一旦 d_ij 为某些 j 定义,它将永远不会随着 j 的增加而改变(提示:归纳)。
对于已修复的 i , d 在 i 中定义为 j 对数(提示:如何将 s_j 的长度作为 j 的函数增加?)。
将此项与您解决的第一项相结合,应该会给出结果以及复杂性证据。
答案 2 :(得分:1)
最多4 ^ k的数字用于确定最多4 ^(k + 1)的数字。这表明在基数4中写n。
考虑我们将数字组合在一起的n的二进制扩展,或者等价于我们写0 =(00),1 =(01),2 =(10)和3 =(11)的基数4扩展。
如果第n个数字是1则设f(n)= +1,如果第n个数字是2则设为-1,其中序列从索引0开始,因此f(0)= 1,f(1)= - 1 ,f(2)-1,f(3)= 1。该索引比从1开始用于计算问题中的示例的索引低一个。基于0的第n位是(3-f(n))/ 2。如果将索引开始为1,则第n位为(3-f(n-1))/ 2.
f((00)n) = f(n).
f((01)n) = -f(n).
f((10)n) = -f(n).
f((11)n) = f(n).
你可以使用它们递归地计算f,但由于它是一个反向递归,你也可以迭代地计算f。 f(n)是( - 1)^(n的二进制权重)=( - 1)^(n的二进制数之和)。