2009年12月21日星期一.sgu499

2009年12月21日星期一.sgu499

2009年12月21日星期一.sgu499
注:此文包括线性筛法,质因子分解,dfs生成一个数的所有因子

sgu499:我想撞墙
http://www.cppblog.com/schindlerlee/
那天arxor看我和angelclover在做,然后也在看题,这个题我还没看,然后arxor大牛就给我说了个想法

把每个数分解素因子,然后dfs出这个数的所有因子。
对每个数进行一次此操作,最后找最大的且被访问了两边以上的因子,
但是这个方法tle在test 20了。怪我当时没细想,被大牛随便一说就觉得这个方法很好。。。。然后。。。杯具了

上代码:tle@20
 1  /*
 2   * SOUR:sgu Greatest Greatest Common Divisor
 3   * ALGO:因子分解
 4   * DATE: 2009年 12月 20日 星期日 19:24:49 CST
 5   * COMM:3http://www.cppblog.com/schindlerlee/
 6   *  */
 7  #include < iostream >
 8  #include < cstdio >
 9  #include < cstdlib >
10  #include < cstring >
11  #include < algorithm >
12  using   namespace  std;
13  typedef  long   long  LL;
14  const   int  maxint  =   0x7fffffff ;
15  const   long   long  max64  =  0x7fffffffffffffffll;
16 
17  const   int  N  =   1000010 ;
18  int  vis[N], n, is_prime[N], primes[N], top;
19  int  exp[ 100 ], num[ 100 ], cnt;
20  int  can[N];
21  void  generate()
22  {
23       int  i, j, k;
24      top  =   0 ;
25      fill(is_prime, is_prime  +  N,  1 );
26       for  (i  =   2 ; i  <=   1000000 ; i ++ ) {
27           if  (is_prime[i]) {
28              primes[top ++ =  i;
29          }
30           for  (j  =   0 ; j  <  top  &&  i  *  primes[j]  <=   1000000 ; j ++ ) {
31              is_prime[i  *  primes[j]]  =   0 ;
32               if  (i  %  primes[j]  ==   0 )
33                   break ;
34          }
35      }
36       // for(i = 0;i < top;i++) {
37       // printf("%d\n",primes[i]);
38       // }
39  }
40 
41  void  factor( int  x)
42  {
43       // printf("factor %d\n",x);
44      cnt  =   0 ;
45       for  ( int  i  =   0 ; i  <  top  &&  x  >   1 ; i ++ ) {
46           if  (x  %  primes[i]  ==   0 ) {
47               // printf("primes[i] = %d\n",primes[i]);
48              can[i] ++ ;
49              num[cnt]  =  primes[i];
50              exp[cnt]  =   0 ;
51               while  (x  %  primes[i]  ==   0 ) {
52                  exp[cnt] ++ ;
53                  x  /=  primes[i];
54              }
55              cnt ++ ;
56          }
57      }
58  }
59 
60  void  dfs( int  x,  int  level)
61  {
62       if  (level  ==  cnt) {
63           // printf("dfs x= %d\n",x);
64          vis[x] ++ ;
65           return ;
66      }
67      dfs(x, level  +   1 );
68       for  ( int  i  =   1 ; i  <=  exp[level]; i ++ ) {
69          x  *=  num[level];
70          dfs(x, level  +   1 );
71      }
72  }
73 
74  int  main()
75  {
76       int  i, j, k;
77      generate();
78      scanf( " %d " & n);
79       for  (i  =   0 ; i  <  n; i ++ ) {
80          scanf( " %d " & k);
81          factor(k);
82          dfs( 1 0 );
83      }
84       for  (i  =  N  -   1 ; i  >=   0 ; i -- ) {
85           if  (vis[i]  >=   2 ) {
86              printf( " %d\n " , i);
87               break ;
88          }
89      }
90       return   0 ;
91  }
92 

然后比赛完google了以下,原来是水题,不予解释了,贴代码
 1 
 2  const   int  N  =   1000010 ;
 3  int  vis[N],n,m;
 4  void  chkmax( int   & x, int  k) {  if (x  <  k) x  =  k; }
 5  int  main()
 6  {
 7       int  i,j,k;
 8      scanf( " %d " , & n);
 9       for (i  =   0 ;i  <  n;i ++ ) {
10          scanf( " %d " , & k);
11          vis[k]  ++ ;
12          chkmax(m,k);
13      }
14 
15       int  res  =   1 ;
16       for (i  =   2 ;i  <=  m;i ++ ) {
17           int  tmp  =   0 ;
18           for (j  =  i;tmp  <   2   &&  j  <=  m;j  +=  i) {
19              tmp  +=  vis[j];
20          }
21           if (tmp  >=   2 ) res  =  i;
22      }
23      printf( " %d\n " ,res);
24
25       return   0 ;
26  }
27 
28 

结果第二天arxor,说他用那个方法过了。。。。。。。。。
然后我看了他的代码,我发现原来我的因子分解是没有优化的。。。
然后把第45行改成
     for  ( int  i  =   0 ; primes[i]  *  primes[i]  <=  x  &&  i  <  top  &&  x  >   1 ; i ++ ) {

过了。。。。。

你可能感兴趣的:(2009年12月21日星期一.sgu499)