[蓝桥杯][2016年第七届真题]最大比例(数论)

Fawn ·
更新时间:2024-11-11
· 534 次阅读

题目描述
X星球的某个大奖赛设了M级奖励。每个级别的奖金是一个正整数。
并且,相邻的两个级别间的比例是个固定值。
也就是说:所有级别的奖金数构成了一个等比数列。比如:
16,24,36,54
其等比值为:3/2

现在,我们随机调查了一些获奖者的奖金数。
请你据此推算可能的最大的等比值。
输入
第一行为数字 N (0<N<100),表示接下的一行包含N个正整数
第二行N个正整数Xi(Xi<1 000 000 000 000),用空格分开。每个整数表示调查到的某人的奖金数额
输出
一个形如A/B的分数,要求A、B互质。表示可能的最大比例系数

测试数据保证了输入格式正确,并且最大比例是存在的。
样例输入
3
1250 200 32
样例输出
25/4
输入:
4
3125 32 32 200

程序应该输出:
5/2

再例如,输入:
3
549755813888 524288 2

程序应该输出:
4/1

思路:我这种做法在dotcpp上面是过了的,但是dotcpp上面数据有没有出错我不太清楚。说一下我的做法吧。我们可以发现,有可能出现相同的数字,相同的数字就代表同一个等级,那么我们排序后去重一下,剩下的就只有不同等级的了。然后每两个相邻的等级之间去遍历有可能出现的情况。利用map保存起来,最后遍历map,选择符合条件的最大值。
这里要说一下,c++中开n次方的方式。传送门

代码如下:

#include #define ll long long #define esp 1e-9 using namespace std; const int maxx=1e5+100; ll a[maxx]; int n; inline ll gcd(ll x,ll y) { if(y==0) return x; else return gcd(y,x%y); } inline ll qsm(ll x,int y) { ll ans=1ll; while(y) { if(y&1) ans*=x; y>>=1; x*=x; } return ans; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); sort(a+1,a+1+n); n=unique(a+1,a+1+n)-a-1; map<pair,int> mp; int j; ll a1,a2; for(int i=2;i<=n;i++) { ll x=gcd(a[i],a[i-1]); a1=a[i]/x; a2=a[i-1]/x; j=1; while(j<40)//这里选择40的原因是开2次方,x有可能是1024*1024*1024*1024,这是2的40次方(不知道这么想对不对) { double b1=pow(a1,1.0/j);//a1开j次方。 double b2=pow(a2,1.0/j); ll c1=(ll)b1; ll c2=(ll)b2; while(qsm(c1,j)<a1) c1++; while(qsm(c2,j)<a2) c2++;//遍历有没有可能同时符合a1和a2. if(qsm(c1,j)==a1&&qsm(c2,j)==a2) mp[make_pair((ll)c1,(ll)c2)]++; j++; } } a1=-1,a2=-1; for(map<pair,int> ::iterator it=mp.begin();it!=mp.end();it++) { if(it->second>=n-1) { if(a1==-1&&a2==-1) a1=it->first.first,a2=it->first.second; else { ll b1=it->first.first; ll b2=it->first.second; if(a1*b2<a2*b1) a1=b1,a2=b2; } } } ll a3=gcd(a1,a2); cout<<a1/a3<<"/"<<a2/a3<<endl; return 0; }

努力加油a啊,(o)/~

starlet_kiss 原创文章 708获赞 174访问量 7万+ 关注 私信 展开阅读全文
作者:starlet_kiss



蓝桥杯 真题 数论

需要 登录 后方可回复, 如果你还没有账号请 注册新账号