【问题标题】:nth term of a sequence序列的第 n 项
【发布时间】:2016-07-14 19:55:50
【问题描述】:

我有两个序列:

1.

8 27 64 125 ...

2.

1 2 3 4 5 6 ....

现在从 1 中取出一个元素,从 2 中取出另一个元素,然后将它们相乘。重复这个。将得到的数字按升序排列。

8 16 24 27 32 40 48 54 56 64 64 ...

我们如何有效地找到这个新序列的n-th 号?

【问题讨论】:

  • 请更具体地说明结果是如何定义的;从这个例子中我不清楚。
  • 你能举一个寻找第n个元素的例子吗?
  • @Codor:好像是两个序列的笛卡尔积。
  • 先取两个序列的笛卡尔积,然后按升序排列
  • 这可能是一个比编程问题更数学的问题。在不知道序列是如何生成的情况下,我不确定你能做的不仅仅是找到第 n 个数字的蛮力方法。如果您确实知道序列是如何生成的(在这种情况下,它似乎是 (n+1)^3n),那么更多的是要查看所涉及术语的数学属性...

标签: math binary-search


【解决方案1】:

如果结果中没有重复的元素,那么我将使用修改后的 埃拉托色尼筛 来标记所有最终序列号,然后创建序列本身的表。这里的C++小例子:

// globals
const int N0=4;
const int N1=6;
const int N2=N0*N1;
const int M=(N0+2)*(N0+2)*(N0+2)*N1;
int f0(int x) { x+=2; return x*x*x; }   // x = <0,N0)
int f1(int x) { x+=1; return x; }       // x = <0,N1)
int f2[N2],n;                           // x = <0,n )

// locals
int x,y;
BYTE soe[M+1];
AnsiString txt="";

// debug print series
for (txt+="f0(x) = ",x=0;x<N0;x++) { txt+=f0(x); txt+=" "; } txt+="\r\n";
for (txt+="f1(x) = ",x=0;x<N1;x++) { txt+=f1(x); txt+=" "; } txt+="\r\n";

tbeg();
// compute sieve
for (x=0;x<=M;x++) soe[x]=0;
for (x=0;x<N0;x++)
 for (y=0;y<N1;y++)
  soe[f0(x)*f1(y)]=1;
// reorder it to table
for (x=0,n=0;x<=M;x++)
 if (soe[x]) { f2[n]=x; n++; }
tend(); txt+="computed in "+tstr(1)+"\r\n";

// debug print ordered series as function of x ... counting from 0
for (txt+="f2(x) = ",x=0;x<n;x++) { txt+=f2[x]; txt+=" "; } txt+="\r\n";

Form1->mm_log->Lines->Add(txt);

结果:

f0(x) = 8 27 64 125 
f1(x) = 1 2 3 4 5 6 
computed in [   0.003 ms]
f2(x) = 8 16 24 27 32 40 48 54 64 81 108 125 128 135 162 192 250 256 320 375 384 500 625 750 

只需忽略 tbeg(),tend(),tstr() 和字符串 Form1-&gt;mm_log,txt 的东西或重写到您的平台/IDE。这还没有优化,可以改进很多......例如,您可以使用每个筛子元素一位而不是BYTE,甚至避免使用内存中的整个筛子表(通过巧妙的排序/分区子结果)。

如果输出中存在重复项,那么您需要使用筛子作为元素的计数器,而不仅仅是布尔值并相应地重建它。

【讨论】:

    猜你喜欢
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-04
    • 2013-04-07
    • 1970-01-01
    • 2019-11-19
    相关资源
    最近更新 更多