题目链接:http://poj.org/problem?id=3489
题目描述:
给定n个数以及x,k,这n个数可以分成k^t( 0<=t )份,比如说其中一个数为6,k为4,可以分为6/4 = 1.5,或者分成6/(4^2) = 0.375,问这些数能否加起来和为x。
即满足:(假设n个数为t1….tn)
x1*(t1/(k^y1)) + x2*(t2/(k^y2))+…………xn*(tn/(k^yn)) = x
关键点就是:
有解的充要条件是,
x能够整除d,(其中d为n个数公约数除以其与k^t的公约数),其中t保证充分大。
推导过程不是很复杂(省略)
推荐一个有详细证明的:
http://www.cppblog.com/menjitianya/archive/2011/04/15/144291.html
#include<cstdio>
#include<iostream>
using namespace std ;
const int MAXM = 100000 ;
int num, pri[MAXM] ;
int gcd(int a, int b){
if( b == 0 ){
return a ;
}
else
return gcd(b,a%b) ;
}
//
int get(int n){
num = 0 ;
for( int i = 2; i*i <= n; i++ ){
if( n % i == 0 ){
pri[num++] = i ;
}
while( n % i == 0 ){
n /= i ;
}
}
if( n != 1 ) pri[num++] = n ;
return num ;
}
///
int main(){
int n, x, k, temp, d = 0 ;
bool res ;
while( cin >> n >> x >> k ){
d = 0 ;
for( int i = 0; i < n; i++ ){
scanf("%d",&temp) ;
if( i == 0 )
d = temp ;
else{
d = gcd(d,temp) ;
}
}
get(k) ;
res = true ;
for( int i = 0; i < num; i++ ){
while( d % pri[i] == 0 ){
d /= pri[i] ;
}
}
if( x % d != 0 )
res = false ;
if( res )
cout << "Yes\n" ;
else
cout << "No\n" ;
}
return 0 ;
}