21南京 J. Xingqiu's Joke 题解(思维+dp)

题目链接

题目思路

比赛的时候差不多想到了

其实就是他们的差值要么不变,要么除以因子,能除肯定要尽可能除

而有很多多余的状态没有必要表示,只要记录哪些dif改变的情况即可其实没那么难,就是要去掉很多表示状态即

代码

#include<bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=2e5+5,inf=0x3f3f3f3f,mod=1e9+7;
const double eps=1e-6;
int n;
int a,b;
map<pii,int> dp;
vector<int> vec;
int dfs(int b,int dif){
    if(b==1) return 0;
    if(dp.count({b,dif})) return dp[{b,dif}];
    int ans=b-1;
    for(auto x:vec){
        if(dif%x==0){
            if(b>=x){
                ans=min(ans,dfs(b/x,dif/x)+b%x+1);
            }
            ans=min(ans,dfs(b/x+1,dif/x)+x-b%x+1);
        }
    }
    return dp[{b,dif}]=ans;
}
signed main(){
    int _;scanf("%d",&_);
    while(_--){
        vec.clear();
        dp.clear();
        scanf("%d%d",&a,&b);
        if(a<b) swap(a,b);
        int dif=a-b;
        for(int i=2;1ll*i*i<=dif;i++){
            if(dif%i==0){
                 while(dif%i==0){
                    dif/=i;
                }
                vec.push_back(i);
            }
        }
        if(dif!=1){
            vec.push_back(dif);
        }
        printf("%d\n",dfs(b,a-b));
    }
    return 0;
}

posted @ 2022-01-19 13:01  hunxuewangzi  阅读(322)  评论(0编辑  收藏  举报