zoukankan      html  css  js  c++  java
  • SRM707 div1 MultiplyAddPuzzle

    题目大意:给定4个数,s,t,a,b

    每次可以将s加a或者乘b,问最少多少次可以得到t

    做法:考虑最后的形式,肯定是s*b^n + a*f(b),f(b)是关于b的多项式

    那么b乘多少次实际上是可以知道的,然后枚举b的次数n

    知道了t - s*b^n,接下来就是求f(b)了

    可以知道,按照b进制做是最优的。

    这里不能只算最大的n,我是把n从0到最大都算了一遍

    因为有些情况较小的n得出的答案会更优。

    还有这题的特殊情况相当多orz

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <vector>
    #include <sstream>
    #include <typeinfo>
    #include <fstream>
    using namespace std;
    typedef long long LL;
    int f[100];
    class MultiplyAddPuzzle {
        public:
        long long minimalSteps(long long s, long long t, long long a, long long b) {
            if(s > t && b != 0) return -1;
            if(s == t) return 0;
            if(b == 1){
                if(a == 0) return -1;
                if( (t-s)%a != 0) return -1;
                return (t-s)/a;
            }
            if(b == 0){
                if(t == 0) return 1;
                if(a == 0) return -1;
                if(t > s && (t-s)%a == 0) return (t-s)/a;
                if( t%a == 0) return t/a+1;
                return -1;
            }
            if(a == 0){
                if(s == 0) return -1;
                if(t%s != 0) return -1;
                LL temp = t/s, ans = 0;
                while(temp != 1){
                    if(temp % b != 0) return -1;
                    ans++; temp /= b;
                }
                return ans;
            }
            LL bt = 0, bpow = 1, temp = 0;
            while(s <= t/bpow){
                if( (t-s*bpow)%a == 0) f[bt] = 1, temp = bt;
                bt++;
                if(bpow > 2e18/b) break;
                bpow *= b;
            }
            bt = temp;
            if(bt == 0) { if( (t-s)%a != 0) return -1; else return (t-s)/a; }
            temp = 1;
            LL ANS = f[0] == 1 ? (t-s)/a : 2e18;
            for(int i = 1; i <= bt; i++) {
                temp *= b;
                if(!f[i]) continue;
                bpow = temp;
                LL ans = i, res = (t-s*bpow)/a;
                while(res > 0){
                    ans += res/bpow;
                    res %= bpow;
                    bpow /= b;
                }
                ANS = min(ANS, ans);
            }
            return ANS;
        }
    };
  • 相关阅读:
    杂项
    导出查询数据(大数据量)
    设置现有字段自增
    C++ 矩形交集和并集的面积-离散化
    Python使用flask架构、跨域
    匈牙利命名法
    C++ main函数
    windows编译boost
    mfc HackerTools监控键盘按键
    mfc HackerTools远程线程注入
  • 原文地址:https://www.cnblogs.com/Saurus/p/7106401.html
Copyright © 2011-2022 走看看