NOIP 模拟 89谜之阶乘
题解 byzjφ
相当于是问是哪一段连乘等于给定的数。
发现连乘的数的个数一定不会很多,最多不会超过 20
所以可以枚举是多少数连乘,有多少数连乘就开几次方,这样得到的数最多和答案连乘的中间数不会超过 5,直接暴力即可。
Code
#include<bits/stdc++.h> #define ri signed #define pd(i) ++i #define bq(i) --i #define func(x) std::function<x> namespace IO{ char buf[1<<21],*p1=buf,*p2=buf; #define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?(-1):*p1++ #define debug1(x) std::cerr << #x"=" << x << ' ' #define debug2(x) std::cerr << #x"=" << x << std::endl #define Debug(x) assert(x) struct nanfeng_stream{ template<typename T>inline nanfeng_stream &operator>>(T &x) { bool f=false;x=0;char ch=gc(); while(!isdigit(ch)) f|=ch=='-',ch=gc(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=gc(); return x=f?-x:x,*this; } }cin; } using IO::cin; namespace nanfeng{ #define FI FILE *IN #define FO FILE *OUT template<typename T>inline T cmax(T x,T y) {return x>y?x:y;} template<typename T>inline T cmin(T x,T y) {return x>y?y:x;} using ll=long long; using ull=unsigned long long; int T; ll st[23],as[23],n; ull jud; auto check=[](ll sa,int len) { ull res=1,lim=sa+len-1; for (ull i(sa);i<=lim;pd(i)) res*=i; return res; }; inline int main() { FI=freopen("factorial.in","r",stdin); FO=freopen("factorial.out","w",stdout); cin >> T; for (ri z(1);z<=T;pd(z)) { cin >> n; if (n==1) {printf("-1\n");continue;} ll res=1; int cnt=1; st[as[cnt]=1]=n; for (ri i(2);i<=20;pd(i)) { if (n/i<res) break; res*=i; ll tmp=ceil(pow(1.0*n,1.0/(1.0*i))); for (ll j(tmp);j<=tmp+5;pd(j)) { if (j-(i>>1)<=1) continue; if ((jud=check(j-(i>>1),i))==n) { st[as[++cnt]=i]=j-(i>>1); break; } else if (jud>n) break; } } printf("%d\n",cnt); for (ri i(cnt);i;bq(i)) printf("%lld %lld\n",st[as[i]]+as[i]-1,st[as[i]]-1); } return 0; } } int main() {return nanfeng::main();}
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步