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
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
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
++
) {
过了。。。。。