解题思路:
1.求等比数列最大的公比,而且题目给出的数据保证有解,一开始考虑等比数列的求和公式啥的,但是对解决题目好像没什么用。
2.然后想到等比数列的定义,an = a1 * qn-1 , 是不是可以把每两个数据的商求出来,消去了a1 , 得到了一个集合{ qi | i >= 1 }。
3.对数据的初步处理解决了,现在问题变成了如何从一些 qi 中获得最大的公比呢?
4.每次从已有的{ qi }集合中找一个未使用过,且 i 最大的qi ,让其与剩下所有(比它小)的相除,如果获得了新的 qi , 加入到集合中。
5.当所有 qi 都已经使用过后,集合中最小的元素就是 最大的公比。
注意事项:
求 集合 { qi } 前已经对数组升序、去重处理,所以得到的 qi 都是严格大于1的。
所以如果 qi > qj ,那么 qi 的分子会比qj 大,而分母也同样如此,但是如果q 是整数的话分母会同为1。
参考代码:
思路大概就如上所述,代码写得比较糙,仅供参考,O(∩_∩)O哈哈~
#include using namespace std; typedef long long ll; ll gcd(ll a,ll b) { return b == 0 ? a:gcd(b,a%b); } struct node { ll a,b; node(ll a,ll b):a(a),b(b){} node(){} bool operator (double)((double)t.a/(double)t.b); } bool operator == (const node&t)const { return (double)((double)a/(double)b) == (double)((double)t.a/(double)t.b); } }; int main(){ int n; cin>>n; ll a; set se; vector ve; for(int i = 1;i>a; if(!se.count(a)) { se.insert(a); ve.push_back(a); } } sort(ve.begin(),ve.end()); set fe; vector vf; for(int i = 0;i<ve.size()-1;i++) { ll p = gcd(ve[i+1],ve[i]); fe.insert(node(ve[i+1]/p,ve[i]/p)); } queue q; bool flag = true; int kcase = 0; while(1) { vf.clear(); for(set::iterator it = fe.begin();it!=fe.end();it++) { vf.push_back(*it); } sort(vf.begin(),vf.end()); // reverse(vf.begin(),vf.end()); if(!flag) { // break; } flag = false; for(int i = kcase++;i= vf.size()){ break; } node t = q.front(); q.pop(); // cout<<t.a<<' '<<t.b<<endl<<endl; while(!q.empty()) { node tem = q.front(); q.pop(); // if(tem==t) continue; node now = node(t.a / tem.a,t.b/tem.b); // cout<<now.a<<' '<<now.b<<endl; if(fe.count(now)) { continue; } else { flag = true; fe.insert(now); } } } cout<<vf[vf.size()-1].a<<'/'<<vf[vf.size()-1].b<<endl; return 0; }
0.0分
13 人评分
C语言程序设计教程(第三版)课后习题6.9 (C++代码)论pow函数的应用浏览:1079 |
点我有惊喜!你懂得!浏览:1166 |
C语言程序设计教程(第三版)课后习题7.3 (C语言代码)浏览:1274 |
printf基础练习2 (C语言代码)浏览:605 |
C语言程序设计教程(第三版)课后习题5.8 (C语言代码)浏览:613 |
C语言训练-求函数值 (C语言代码)浏览:600 |
C语言训练-求s=a+aa+aaa+aaaa+aa...a的值 (C语言代码)浏览:636 |
【偶数求和】 (C语言代码)浏览:588 |
C语言程序设计教程(第三版)课后习题6.1 (C语言代码)浏览:769 |
Tom数 (C语言代码)浏览:517 |