codevs 2190 有理逼近 题解
2014-10-21 20:02
169 查看
题目描述 Description
对于一个素数P,我们可以用一系列有理分数(分子、分母都是不大于N的自然数)来逼近sqrt(p),例如P=2,N=5的时候:1/1<5/4<4/3<sqrt(2)<3/2<5/3<2/1。
任 务 :
给定P、N(N>sqrt(p)),求X、Y、U、V,使x/y<sqrt(p)<u/v且x/y与sqrt(p)之间、sqrt(p)与u/v之间都不能再插入满足题意的有理分数。
输入描述 Input Description
输入文件的第一行为P、N
输出描述 Output Description
输出文件只有一行,格式为“X/Y U/V”。注意,答案必须是既约的,也就是说分子、分母的最大公约数必须等于1。
样例输入 Sample Input
样例1:
2 5
样例2:
5 100
样例输出 Sample Output
样例1:
4/3 3/2
样例2:
38/17 85/38
数据范围及提示 Data Size & Hint
P、N<30000
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
说实话,这道题真的把我唬住了……
刚看到这道题,感觉明显的二分,可是如何分?怎么分?是一个问题。
于是我想我没可以枚举分子和分母,然后找最接近的,然而 P、N<30000这的把我唬住了…
…尽管我看见了gcd(分子,分母)=1这个提示,但是我还是没有去写它(事实证明,这题很水,暴力可以a)
在时间竟破的情况下,我选择了放弃……
中午评测完以后,我发现,我们可以枚举固定区间内的分子,因为分母是从2-n的,那些远大于 分母*(p)^(1/2)的分子
是没有必要去枚举的。所以我们可以取(p)^(1/2)的上界和下界(即上下取整)这样我们可以把每一个分母的分子限制
在一个很小的区间内,再加上gcd(分子,分母)=1,还有二分枚举答案,这题就可以过了。
由于本人不会写二分,所以,我开了一个大根堆,一个小根堆来维护。看来,今晚还要补习一下二分了!!
注意:有可能输出如1/1或者2/1的情况!!
+++++++++++++++++++++代码如下++++++++++++++++++++++++++++++++++++
题目描述 Description
对于一个素数P,我们可以用一系列有理分数(分子、分母都是不大于N的自然数)来逼近sqrt(p),例如P=2,N=5的时候:1/1<5/4<4/3<sqrt(2)<3/2<5/3<2/1。
任 务 :
给定P、N(N>sqrt(p)),求X、Y、U、V,使x/y<sqrt(p)<u/v且x/y与sqrt(p)之间、sqrt(p)与u/v之间都不能再插入满足题意的有理分数。
输入描述 Input Description
输入文件的第一行为P、N
输出描述 Output Description
输出文件只有一行,格式为“X/Y U/V”。注意,答案必须是既约的,也就是说分子、分母的最大公约数必须等于1。
样例输入 Sample Input
样例1:
2 5
样例2:
5 100
样例输出 Sample Output
样例1:
4/3 3/2
样例2:
38/17 85/38
数据范围及提示 Data Size & Hint
P、N<30000
对于一个素数P,我们可以用一系列有理分数(分子、分母都是不大于N的自然数)来逼近sqrt(p),例如P=2,N=5的时候:1/1<5/4<4/3<sqrt(2)<3/2<5/3<2/1。
任 务 :
给定P、N(N>sqrt(p)),求X、Y、U、V,使x/y<sqrt(p)<u/v且x/y与sqrt(p)之间、sqrt(p)与u/v之间都不能再插入满足题意的有理分数。
输入描述 Input Description
输入文件的第一行为P、N
输出描述 Output Description
输出文件只有一行,格式为“X/Y U/V”。注意,答案必须是既约的,也就是说分子、分母的最大公约数必须等于1。
样例输入 Sample Input
样例1:
2 5
样例2:
5 100
样例输出 Sample Output
样例1:
4/3 3/2
样例2:
38/17 85/38
数据范围及提示 Data Size & Hint
P、N<30000
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
说实话,这道题真的把我唬住了……
刚看到这道题,感觉明显的二分,可是如何分?怎么分?是一个问题。
于是我想我没可以枚举分子和分母,然后找最接近的,然而 P、N<30000这的把我唬住了…
…尽管我看见了gcd(分子,分母)=1这个提示,但是我还是没有去写它(事实证明,这题很水,暴力可以a)
在时间竟破的情况下,我选择了放弃……
中午评测完以后,我发现,我们可以枚举固定区间内的分子,因为分母是从2-n的,那些远大于 分母*(p)^(1/2)的分子
是没有必要去枚举的。所以我们可以取(p)^(1/2)的上界和下界(即上下取整)这样我们可以把每一个分母的分子限制
在一个很小的区间内,再加上gcd(分子,分母)=1,还有二分枚举答案,这题就可以过了。
由于本人不会写二分,所以,我开了一个大根堆,一个小根堆来维护。看来,今晚还要补习一下二分了!!
注意:有可能输出如1/1或者2/1的情况!!
+++++++++++++++++++++代码如下++++++++++++++++++++++++++++++++++++
<span style="font-family:Comic Sans MS;font-size:18px;">#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <queue> #include <vector> using namespace std; struct node1{ int son,mot;double w; bool operator < (const node1 &a) const { return w<a.w; } }a[3001000]; int n,q; double p; struct node2{ int son,mot;double w; bool operator < (const node2 &a) const { return w>a.w;//×îСֵÓÅÏÈ } }b[3001000]; priority_queue<node1>q1; priority_queue<node2>q2; int gcd(int x,int y) { return y?gcd(y,x%y):x; } int main() { cin>>q>>n;p=sqrt(q); int l=floor(sqrt(q)),r=ceil(sqrt(q)); for(int k=1,kk=1,i=2;i<=n;i++) for(int j=i*l;j<=min(n,i*r);j++) if(gcd(i,j)==1) { double jj,ii,z; jj=(double)j; ii=(double)i; z=jj/ii;//cout<<<<endl; if(z<p) { a[k].son=j; a[k].mot=i; a[k].w=z; q1.push(a[k]);k++; } if(z>p) { b[kk].son=j; b[kk].mot=i; b[kk].w=z; q2.push(b[kk]);kk++; } } if(!q1.empty()) cout<<q1.top().son<<"/"<<q1.top().mot<<" "; else cout<<l<<"/"<<1<<" "; if(!q2.empty()) cout<<q2.top().son<<"/"<<q2.top().mot; else cout<<r<<"/"<<1; return 0; }</span>
题目描述 Description
对于一个素数P,我们可以用一系列有理分数(分子、分母都是不大于N的自然数)来逼近sqrt(p),例如P=2,N=5的时候:1/1<5/4<4/3<sqrt(2)<3/2<5/3<2/1。
任 务 :
给定P、N(N>sqrt(p)),求X、Y、U、V,使x/y<sqrt(p)<u/v且x/y与sqrt(p)之间、sqrt(p)与u/v之间都不能再插入满足题意的有理分数。
输入描述 Input Description
输入文件的第一行为P、N
输出描述 Output Description
输出文件只有一行,格式为“X/Y U/V”。注意,答案必须是既约的,也就是说分子、分母的最大公约数必须等于1。
样例输入 Sample Input
样例1:
2 5
样例2:
5 100
样例输出 Sample Output
样例1:
4/3 3/2
样例2:
38/17 85/38
数据范围及提示 Data Size & Hint
P、N<30000
相关文章推荐
- codevs 2190 有理逼近
- [FT][2]codevs 2190 有理逼近
- 【BZOJ2190】【codevs2296】仪仗队,数论练习之φ的线性筛
- Tyvj P1077 CODE[VS] 2190 有理逼近
- 【BZOJ1044】【tyvj3511】【codevs1870】木棍分割,二分答案+滚动数组+前缀和DP
- vscode设置备份
- codevs1928 加密算法 数论[四星]
- VS 下 Open Cascade Source Code 编译及自定义工程设置()
- [codevs1576] 最长严格上升子序列
- 矩形周长(codevs 2149)
- 个人VS Code配置文件JSON
- Codevs_P3186 队列练习2
- CODE[VS] 1014 装箱问题
- 过河[NOIP2015提高组][Codevs 1105]
- codevs 1230_元素查找_hash
- Codevs 1018 单词接龙
- VS Code开发技巧集锦
- Codevs_P2981 查字典1(BIT)
- 最短回文串[Codevs 3962]
- Codevs 1004 四子连棋