3 solutions

  • 1
    @ 2025-12-14 17:00:31
    1. 对于任意进制 bb , nn 在 bb 进制下的数位和 f(b,n)f(b,n) 一定小于 nn(当 b>nb>n 时, f(b,n)=n f(b,n)=n ,这是特殊情况)。因此:
    • 若 s>ns>n :直接输出 1-1 (不可能存在满足条件的进制)。
    • 若 s=ns=n :最小进制为 n+1n+1(此时 nn 在 n+1n+1 进制下是个位数,数位和为自身)。
    1. 进制的范围:
    • 当 bnb\leq\sqrt{n} 时:可直接枚举所有可能的进制,计算其数位和是否等于 ss
    • 当 b>nb>\sqrt{n} 时, nn 在 bb 进制下为两位数 qb+rqb+rq=n/bq=\lfloor n/b \rfloorr=nmodbr=n\mod b ),数位和为 q+r=sq+r=s。结合 n=qb+rn=qb+r ,可得 ns=q(b1)n-s=q(b-1) ,即 qq 是 nsn-s 的约数。枚举 qq 从 11 到 n\sqrt{n} (因 q=(ns)/(b1)q=(n-s)/(b-1) ,且 b>nb>\sqrt{n} 时 q<nq<\sqrt{n} ):若 (ns)(n-s) 能被 qq 整除,计算 b=(ns)/q+1b=(n-s)/q+1 。验证 b>nb>\sqrt{n} 且 f(b,n)=sf(b,n)=s ,若满足则输出 bb
    #include<bits/stdc++.h>
    using namespace std;
    #define FAST_IO ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
    #define int long long
    #define MAXN 100005
    int n,s;
    int __sqrt(int x)
    {
        if(x==0) return 0;
        int l=1,r=x;
        while(l<=r)
    	{
            int mid=l+(r-l)/2;
            if(mid<=x/mid) l=mid+1;
            else {r=mid-1;}
        }
        return r;
    }
    int f(int b,int n)
    {
    	if(n<b) return n;
    	else {return f(b,n/b)+n%b;}
    }
    signed main()
    {
    	FAST_IO;
    	cin>>n>>s;
    	if(s>n) {cout<<"-1\n";return 0;}
    	if(s==n) {cout<<n+1<<'\n';return 0;}
    	int sq=__sqrt(n);
    	for(int i=2;i<=sq;i++)
    	{
    		if(f(i,n)==s) {cout<<i<<'\n';return 0;} 
    	}
    	for(int i=sq;i>=1;i--) 
    	{
    		int val=(n-s)/i+1;
    		if((n-s)%i==0&&f(val,n)==s) {cout<<val<<'\n';return 0;}
    	}
    	cout<<"-1\n";
    	return 0;
    }
    
    • 1
      @ 2025-12-10 21:31:01
      #include<bits/stdc++.h>
      using namespace std;
      #define int long long
      
      signed main() {
      	// 1. 新增:输入加速(解决大数据量超时,必加)
      	ios::sync_with_stdio(false);
      	cin.tie(nullptr);
      
      	int n, s;
      	cin >> n >> s;
      	if (n < s) {
      		cout << -1 << '\n'; // 2. 加换行符(格式错误)
      		return 0;
      	} else if (n == s) {
      		cout << n + 1 << '\n'; // 加换行符
      		return 0;
      	}
      	// 小b枚举(你的逻辑,无错)
      	for (int i = 2;  i <= n / i; i++) {
      		int total = 0;
      		int temp = n;
      		while (temp > 0) {
      			total += temp % i;
      			temp /= i;
      		}
      		if (total == s) {
      			cout << i << '\n'; // 加换行符
      			return 0;
      		}
      	}
      	vector<int> k;
      	int diff = n - s; // 新增:简化n-s的重复计算
      	// 3. 修正:因数枚举完整(取消注释,处理j和(n-s)/j)
      	for (int j = 1; j <= n / j; j++) {
      		if (diff % j != 0) continue;
      		k.push_back(j);
      		//	k.push_back(diff / j); // 取消注释,补全因数
      	}
      	// 4. 修正:min_b初始化逻辑(对齐正确代码的ans=-1)
      	sort(k.begin(), k.end());
      	// 去重(避免重复因数导致重复计算)
      	reverse(k.begin(), k.end());
      	int kt = sqrt(n);
      	for (auto i : k) {
      		int b = diff / i + 1;
      		// 防御性检查:保证b≥2(避免无效b)
      		if (b <= kt) continue;
      		int st = n / b + n % b;
      		// 5. 修正:找到第一个合法b就记录,或取最小(对齐正确代码)
      		if (st == s) {
      
      			cout << b;
      			return 0;
      
      		}
      	}
      
      
      	cout << -1 << '\n';
      	return 0;
      }
      
      • 0
        @ 2025-12-14 14:59:10

        分类讨论:
        (n)b(n)_b 是一位数时,必有 f(b,n)=nf(b,n)=n。这一部分可以特判掉(nsn \le s)。
        (n)b(n)_b 为至少三位的数,n2>bn^2 > b。此时一定有 bnb \le \sqrt{n}。循环解决。
        否则, (n)b(n)_b 是两位数,则:
        n=bk+pn=bk+p
        s=k+ps=k+p
        ns=(b1)kn-s=(b-1)k
        因此可以枚举 (ns)(n-s) 的因数进行判断。
        总时间复杂度 O(n)O(\sqrt{n}),可以通过。

        #include<bits/stdc++.h>
        #define please using
        #define dont namespace
        #define copy std
        please dont copy;
        long long f(long long b,long long n){
        	if(n<b)return n;
        	return f(b,n/b)+n%b;
        }
        int main(){
        	long long n,s;
        	scanf("%lld%lld",&n,&s);
        	if(n<s){
        		puts("-1");
        		return 0;
        	}
        	if(n==s){
        		printf("%lld",n+1);
        		return 0;
        	}
        	long long x=sqrt(n)+1;
        	for(long long i=2;i<=x;i++){
        		if(f(i,n)==s){
        			printf("%lld",i);
        			return 0;
        		}
            }
        	long long ans=0;
        	for(long long i=1;i<=x;i++){
        		if((n-s)%i)continue;
        		if(f((n-s)/i+1,n)==s)ans=(n-s)/i+1;
            }
        	if(ans==0)puts("-1");
        	else printf("%lld",ans);
        }
        
        • 1

        Information

        ID
        608
        Time
        1000ms
        Memory
        256MiB
        Difficulty
        8
        Tags
        (None)
        # Submissions
        42
        Accepted
        8
        Uploaded By