D. Another Problem About Dividing Numbers
题意:a,b,k3个数。问a和b能否通过k次操作,让a和b相等。其中每次操作是选一个c能整除a或者b,然后a/c或者b/c。输出yes或者no。
思路:有点像图的问题,但是可以从质因子数量这一块入手。先线性筛,然后对于输入a和b,如果两个数的质因子数量 >= k,那么则可以通过刚好k次操作让他们都变成1。如果质因子数量和 < k,那么不可能变相等。另外,k > 60多的时候,也不可能变相等。因为对于最大输入1e9,最多只有29.几个质因子2。 还有,对于k = 1的情况要单独讨论,因为k = 1时,只有而且必须有一个数进行操作。此时ab中有一方需能被另一方整除,并且ab不相等才可以。
总结:思路有点模糊,也是写一步想一步,对于k =1的情况没有考虑到,是跑了测试样例才知道的。求出质因子数量后其他的就好说了,还是要考虑一下极端输入样例。
vector<int> prime_values;
bitset<33333> bs;
void sievePrimes(int x = 32222){
bs.set();
bs[0] = bs[1] = 0;
for (int i = 2; i <= x; ++i){
if (bs[i]){
prime_values.emplace_back(i);
}
for (const auto& prime : prime_values){
if (1ll * i * prime > x){
break;
}
bs[i * prime] = 0;
if (i % prime == 0){
break;
}
}
}
}
void preProcess(){
sievePrimes();
}
void solve(){
int a, b, k;
cin >> a >> b >> k;
if (k >= 65){
cout << "No" << '\n';
}
else{
multiset<int> prime_a;
multiset<int> prime_b;
auto getPrimes = [](multiset<int>& cur_set, int x) -> void{
for (const auto& prime : prime_values){
while (x % prime == 0){
x /= prime;
cur_set.insert(prime);
}
}
if (x > 1){
cur_set.insert(x);
}
};
getPrimes(prime_a, a);
getPrimes(prime_b, b);
int sz_a = (int)prime_a.size();
int sz_b = (int)prime_b.size();
if (sz_a + sz_b < k){
cout << "No\n";
}
else if (k == 1){
if (a < b){swap(a, b);}
if (a % b == 0 && a != b){
cout << "Yes\n";
}
else{
cout << "No\n";
}
}
else{
cout << "Yes\n";
}
}
}

浙公网安备 33010602011771号