Chinaunix首页 | 论坛 | 博客
  • 博客访问: 424974
  • 博文数量: 103
  • 博客积分: 1455
  • 博客等级: 上尉
  • 技术积分: 1380
  • 用 户 组: 普通用户
  • 注册时间: 2012-09-15 22:17
文章分类

全部博文(103)

文章存档

2013年(4)

2012年(99)

我的朋友

分类: C/C++

2012-10-23 20:27:08

这道题是从跑黑同学的博客上看到的
runningdark.blog.chinaunix.net
看了之后在gcc上跑了一下,觉得好像少了一个从0开始的最小计数,而且getnextoccur这个子函数没有看懂,于是在他的思路之上修改了一下,去掉了getnextoccur函数,全部用getfirstvalue函数实现得到以下的代码:

点击(此处)折叠或打开

  1. /*

  2.  * =====================================================================================

  3.  *

  4.  * Filename: bead.c

  5.  *

  6.  * Description:

  7.  *

  8.  * Version: 1.0

  9.  * Created: 10/20/2012 11:46:48 AM

  10.  * Revision: none

  11.  * Compiler: gcc

  12.  *

  13.  * Author: royn.wang.renyuan@gmail.com (),

  14.  * Organization:

  15.  *

  16.  * =====================================================================================

  17.  */

  18. #include <stdlib.h>

  19. #include <stdio.h>



  20. #define MAXK 10

  21. #define MAXM 100 /* */

  22. int getfirstvalue(int i,int *input,int n,int size){

  23.     int match = (1<<n)-1;

  24.     int end = i-1;

  25.     int v = 0;

  26.     do{

  27.         end++;

  28.         v |= 1<<input[end%size];

  29.     }while(v!=match);

  30.     return end;

  31. }

  32. /*
  33. int getnextoccur(int tarindex, int *input, int size){

  34.     int i;

  35.     for(i = tarindex+1;i<size*2;i++){

  36.         if( input[i%size] == input[tarindex])

  37.             return i%size;

  38.     }

  39.     return -1;

  40. }
  41. */


  42. /*

  43.  * === FUNCTION ======================================================================

  44.  * Name: main

  45.  * Description:

  46.  * =====================================================================================

  47.  */

  48.     int

  49. main ( int argc, char *argv[] )

  50. {

  51.     int input[] = {0,1,2,3,4,4,5,4,2,3,1,0,2,3,3,1,1,0,3,2,1,4,5,3,4,2,4,1,0,5};

  52.     int n = 6;

  53.     int size = sizeof(input)/sizeof(int);

  54.     int end[size];

  55.     int endnum;

  56.     int i = 0;

  57.     int minlen = size;

  58.     for(i = 0; i<size;i++){

  59.         end[i] = getfirstvalue(i,input,n,size);
  60.     
  61.     endnum=end[i]%size;

  62.         printf ( "start = %d end = %d\n", i,endnum );

  63.         minlen = (end[i]-i+1)>minlen? minlen : end[i]-i+1;

  64.     }

  65.     printf ( "min length = %d\n", minlen );

  66.     return EXIT_SUCCESS;

  67. } /* ---------- end of function main ---------- */
我的思路呢,就是把每一颗珠子遍历一遍,求出每一个的最小值,然后比较minlen
如果小于minlen就修改minlen的值
求最小值的方法借用了跑黑同学左移填满数据位的方法
阅读(1363) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

runningdark2012-10-25 20:51:44

nextoccur就是当前数字在下次出现的位置。每次向后移动的时候,它的前一个珠子的下一次出现的位置如果在当前的串中,说明上个珠子可以删掉。长度就可以缩减一个。比如4,5,4,2,3,1,0这个序列(4~11),向后移一位,就是5,4,2,3,1,0, 去掉的那个4的nextoccur值是7,刚好输入的第七个元素在这个新串里。所以说明这个4去掉是合法的。相反的如多过去掉的4 的nextoccur是15,那么说明这个串要扩展到第15个元素才能保证符合条件。这个方式是为了降低算法复杂度。如果都用getfirstvalue,那么算法复杂度就高了。使用这个辅助的nextoccur,是想让它成线性复杂度。但是不幸的是,nextoccur是n平方复杂度的。如果能把这个想法改成线性的,就差不多了。不过整个过程还是太繁琐了。