Codeforces Round #725 (Div. 3) D

题目大意:

给你三个数a,b,k

有两种操作:每次找一个大于1的数c,将a变成a/c(a%c==0),或者将b变成b/c(b%c==0)

问是否刚好用k次操作使得a==b

 

思路:

1.dfs

如果a<b 先swap一下,确保a>=b

初始:

dfs(a,b,k)

转移:

当a%i==0时,dfs(a/i,b,k-1)

(然而当a和b都超级大的时候会超时)

 

2.

设a和b相等需要的最小次数为l,最大次数为r

容易发现,当 l<=k<=r时 输出YES,否则输出NO

问题转换为求l和r

 

code:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int t,a,b,k;
bool f=0;
int l,r;

int cal(int x){
  if(x==1) return 0;
   else if(x<4) return 1;
  int cnt=0;
  ll res=0;
  int maxx=sqrt(x);
  for(int i=2;i<=maxx;i++){
    if(x==1) break;
    if(x%i==0){
      while(x%i==0){
        x/=i;
        cnt++;
      }
      res+=cnt;
      cnt=0;
    }
    if(i==maxx&&x>1){
      res+=1;
    }
  }
  return res;
}

void solve(){
  if(a==b) l=0;
  else if(a%b==0||b%a==0) l=1;
  else l=2;
  r=cal(a)+cal(b);
}

bool check(){
  if(k<=r&&k>=l) return 1;
  return 0;
}

int main(){
  scanf("%d",&t);
  while(t--){
    f=0;
    scanf("%d",&a);scanf("%d",&b);scanf("%d",&k);
    if(a==b&&k==1){
    puts("NO");
    continue;
  }
    solve();
    // cout<<l<<" "<<r<<endl;
    if(check()) puts("YES");
    else puts("NO");
  }
  return 0;
}

 

posted @ 2021-06-12 20:03  starlightlmy  阅读(46)  评论(0)    收藏  举报