codeforces 337E E. Divisor Tree(数论+贪心)

题目链接:

codeforces 337E

题目大意:

给出n个数,要求用到全部这些数,,构建一棵每个点权值是孩子的权值之积,每个叶子节点的权值是一个质数的数,问这棵树最少需要多少个节点。

题目分析:为什么从大到小开始选呢,因为较小的才有可能是较大的数的约数,所以如果后面的数已经是前面的约数的时候,那么它的质因数不会导致新的叶子,按这个顺序做方便统计。 AC代码:;LL;bool prime[MAX],mark[10];LL num[20];void init ( ){memset ( prime , true , sizeof ( prime ) );prime[1] = prime[0] = false;for ( LL i = 2; i < MAX ; i++ )if ( prime[i] )for ( LL j = i*i ; j < MAX ; j+= i )prime[j] = false;}LL get ( LL num ){LL ret = 0;for ( LL i = 2 ; i*i <= num ; i++ ){if ( num%i ) continue;if ( !prime[i] ) continue;while ( num%i==0 ){num /= i;ret++;}}if ( num > 1 ) ret++;return ret;}LL ans,a[30];int n;bool cmp ( LL a , LL b ){return a > b;}void solve ( int x ){if ( !mark[x] ) ans++;LL temp = a[x];while ( true ){int j = -1;for ( int i = x+1; i < n ; i++ ){if ( mark[i] ) continue;if ( temp%a[i] ) continue;if ( j== -1 || num[j] < num[i] )j = i;}if ( j == -1 ) break;temp /= a[j];mark[j] = true;if ( num[j] > 1 ) ans++;}if ( !mark[x] && num[x] > 1 )ans += num[x];mark[x] = true;}int main ( ){init ( );while ( ~scanf ( “%d” , &n ) ){ans = 0;for ( int i = 0 ; i < n ; i++ )scanf ( “%lld” , &a[i] );sort ( a , a+n , cmp );for ( int i = 0 ; i < n ; i++ )num[i] = get ( a[i] );memset ( mark , 0 , sizeof (mark) );int cnt = 0;for ( int i = 0 ; i < n ; i++ ){if ( !mark[i] ){cnt++;}solve ( i );}if ( cnt > 1 ) ans++;//if ( a[0] == 658912949530 && ans == 24 ) ans–;printf ( “%lld\n” , ans );}}

你的选择是做或不做,但不做就永远不会有机会

codeforces 337E E. Divisor Tree(数论+贪心)

相关文章:

你感兴趣的文章:

标签云: