P8814(CSP-J2022T2)题解
题意:给定一个正整数 k,有k 次询问,每次给定三个正整数 n, e, d,求两个正整数 p, q,使 n = p × q且e × d = (p − 1) × (q − 1) + 1。
思路:通过题意可以发现,ed = pq - p - q + 1 + 1。
则ed = pq - p - q + 2
ed = n - p - q + 2
p + q = n - ed + 2
那么我们知道了p + q = n - ed + 2和pq = n两个条件就可以二分啦!(二分实际上就是根据用铁丝围成一个矩形,长宽之差越大,面积越小,长宽之差越小,面积越大的原理,长宽即是 pq)。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | #include<cstdio> #include<algorithm> #define ll long long using namespace std; ll n,e,d,m; bool check(ll x) //check函数 { ll a=x,b=m-x; if (a*b<n) //如果大了 { return 1; } else //如果小了 { return 0; } } void solve() { scanf ( "%lld %lld %lld" ,&n,&e,&d); m=n-e*d+2; ll l=0,r=m; while (l<=r) //二分 { ll mid=(l+r+1)>>1; if (check(mid)) { l=mid+1; } else { r=mid-1; } } for (ll i=l-5;i<=l+5;i++) //为了AC而扩大了范围 { if (i<=0) { continue ; } if (n%i==0&&(n/i)==(m-i)) { printf ( "%lld %lld\n" ,min(i,m-i),max(i,m-i)); return ; } } printf ( "NO\n" ); return ; } int main() { ll q; scanf ( "%lld" ,&q); while (q--) { solve(); } return 0; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?