Chinaunix首页 | 论坛 | 博客
  • 博客访问: 61855
  • 博文数量: 18
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 210
  • 用 户 组: 普通用户
  • 注册时间: 2008-09-26 16:04
文章分类

全部博文(18)

文章存档

2011年(1)

2009年(3)

2008年(14)

我的朋友

分类: C/C++

2008-10-07 17:17:25

算法题:
想产生一个数列:T(n) = T(n-1),n,T(n-1),T(0) = 1
不用递归
比如T(3)是1,2,1,3,1,2,1
T(4)是1,2,1,3,1,2,1,4,1,2,1,3,1,2,1(2^n-1)
------------------------------------------------
我首先分析了一下这个数列,发现
a.T(n)有2^n-1个元素
b.中间的元素值是n,以n为中心,两边的子序列中心元素是n-1,依次类推,最后剩下的都是1
c.下面给出两个方案的c语言伪代码

方案1,对于n不是很大的情况,直接生成整个序列
--------------------内存中要存在的
T(n)=new int[2^n-1];
for(int i=0;i         //i代表值为2^i的值元素,共2^(n-i-1)个,例如i=0代表1的个数,T(3)里面共4个1
        for(int m=0;m<2^(n-i-1);++m){
                T(n)[m*2^i]=2^i;
        }               
}
方案1算法复杂度O(n)*O(2^n)

方案2,对于n比较大的,只能逐个打印元素到屏幕或者一个大文件,因为内存可能不够用
--------------------内存中不存在的
int j=2^n-1;
for(int s=0;s    Tnj=f(s);
   printf(Tnj);
}
int f(int sub){//O(n)
   int i=sub+1;//第i个元素,sub是从0开始的
   if(i>2^n-1)i=(j+1)-i;//对称,所以只考虑前半个序列的规律就可以,后半个序列值对称
   /*
    *分析,如果i最高位是1其他都是0(100)它的值就是n
    *例如T(4)里面第5个元素位置0101,除2不尽,所以值=1
    *    发现1的位置有规律,001,011,101,111,末尾没有0,
    *    2的位置010,110,末尾一个0,3的位置是末尾2个0
    *
    *    位置的个数是n,所以算法复杂度是还是O(2^n)*O(n)
    *    有没有改进的,计算一个整数的2进制表示,后面有几个0
    */
   int return=1;
   while(i%2==0){//这个循环while能否改进?
      ++return;
      i>>1;
   }
}
上述算法的复杂度仍然是O(n)*O(2^n)。我感觉问题主要存在于计算一个整数的2进制表示最后有几个0
->例如第5个元素位置是101,那么末尾是0个0,它的值就是1+0=1
  第6个元素的位置是110,末尾1个0,它的值就是1+1=2

#include <stdio.h>
#include <stdlib.h>

void solve(int n) {
  int s[100], t = 0, i;
  for (i = n; i; s[t++] = i--)
    ;
  while (t) {
    printf("%d ", s[--t]);
    for (i = s[t] - 1; i; s[t++] = i--)
      ;
  }
  printf("\n");
}

int main(int argc, char *argv[]) {
  int n = atoi(argv[1]);
  solve(n);
  return 0;
}

阅读(823) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~