43/45求调
查看原帖
43/45求调
602968
Wangziruican楼主2024/10/14 10:24
#include<iostream>
#include<cmath>
#define ll unsigned long long
using namespace std;
ll n,s,p=1,b;//p记录当前加数 
bool flag=1;
ll f(ll x,ll y){
	ll ans=0;
	while(x>=y){
		ans+=x%y;
		x=floor(1.0*x/y);
	}
	ans+=x;
	return ans;
}
int main(){
	//以87654为例 i指b 
	//结论1 当i=n以上,结果为n
	//现象1 当i=(87654)时,结果为1,i每减1,结果+1,直到(43828),此时结果为(43827);
	//现象2 当i=(43827)时,结果为2,i每减1,结果+2,直到(29219) ,此时结果为(29218);
	//现象3 当i=(29218)时,结果为3,i每减1,结果+3,直到(21914) ,此时结果为(21916);
	//现象4 当i=(21913)时,结果为6,i每减1,结果+4,直到(17531) ,此时结果为(17534);
	//现象5 当i=(17530)时,结果为9,i每减1,结果+5,直到(14610) ,此时结果为(14609);
	//现象6 当i=(14609)时,结果为6,i每减1,结果+6,直到(12523) ,此时结果为(12522);
	//现象7 当i=(12522)时,结果为7,i每减1,结果+7,直到(10957) ,此时结果为(10962);
	//现象8 当i=(10956)时,结果为14,i每减1,结果+8,直到(9740) ,此时结果为(9742);
	//现象9 当i=(9738)时,结果为12,i每减1,结果+9,直到(8766) ,此时结果为(8769);
	//现象10 当i=(8765)时,结果为14,i每减1,结果+10,直到(7969) ,此时结果为(7974); 
	//现象11  此规律到311失效 此时每次加280; 
	//结论2 从i=n开始,到i=n/2+1,值yu在1~n/2 (n偶数) 1~n/2+1(n奇数) 
	//结论3 假设加值为p 若i-结果小于(等于?)p, 则不断i--,结果+p 如果超出,则p++,重新计算 
	cin>>n>>s;
//	if(s>n){
//		cout<<-1;
//		return 0;
//	}
	if(s==n){//结论1的应用 (可以省略/优化)
		cout<<n+1;
		return 0;
	}
	if(s>n){
		cout<<-1;
		return 0;
	}
	for(ll i=n;;){
		if(p==1){//特殊情况 
			if(s>=1&&s<=n/2+1){//s在大范围内; 
				if(s%2==1||((s%2==0)&&s!=n/2+1)){//奇数不用管,偶数需要看一下是否越界 
					b=i-s+1;
					flag=0;
				}
			}
			//p等于2的时候,i=n/2(i/2); 
			i=i/2;
			p++;
		}else{
			ll base=f(n,i);//记录初始值 
			if(f(n,i-1)-f(n,i)==p){//规律仍成立 (等于?)
				//此时假设i减少k 则base增加p*k 找到k使(新i-新base)>0,((新base+p)-(新i-1))<0;
				//等价于 k=(i-base)/(p+1)
				//此时以p为加数的最后一位为i-k
				ll k=(i-base)/(p+1);
				ll i2=i;//记录原来的i 
				i=i-k;
				ll end=f(n,i);//记录末值 
				if(s>=base&&s<=end&&(s-base)%p==0){//符合条件 
					b=i2-(s-base)/p;
					flag=0;
				}
				//新i,p; 
				p++;
			}else{
				if(s==base){
					b=i;
					flag=0;
				}
			}
			i--;
		}
		if(i==2){
			break;
		}
	}
	//i=2特判;
	if(s==f(n,2)){
		b=2;
		flag=0;
	}
	if(flag){
		cout<<-1;
	}else{
		cout<<b;
	}
	return 0;
} 
2024/10/14 10:24
加载中...