题目描述
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万+ 关注 私信 展开阅读全文