X星球的某个大奖赛设了M级奖励。每个级别的奖金是一个正整数。
并且,相邻的两个级别间的比例是个固定值。
也就是说:所有级别的奖金数构成了一个等比数列。比如:
16,24,36,54
其等比值为:3/2
现在,我们随机调查了一些获奖者的奖金数。
请你据此推算可能的最大的等比值。
输入格式:
第一行为数字N(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
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 3000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。 所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0 注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。 注意:
所有依赖的函数必须明确地在源文件中 #include , 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型。
题目大意就是给出一个等比数列的若干项,求出这个等比数列的最大等比。
排序后,把相邻的两项间隔比求出来,设为比例数列 {a1/b1, a2/b2, … an/bn},那么需要找到一个最大的p/q,使得数列里面的每个 ai/bi = (p/q)^K,类似最大公倍数。
由于最大数也是10^12,即使底为2,最大幂也只是40,不妨枚举幂的大小,枚举并验证。标程为了避免开方的精度问题,进行了简单的预处理,二分亦可。注意一些细节的处理,精度、溢出等等。
#include <stdio.h>
#include <math.h>
#include <set>
#include <iostream>
using namespace std;
long long gcd(long long x, long long y) {
return x % y == 0 ? y : gcd(y, x % y);
}
int a[1001];
int b[1001];
long long Pow(int x,int n)
{
long long ans=1;
for(int i=1;i<=n;i++)
ans*=x;
return ans;
}
int test(int aa,int bb,int ai,int bi)
{
for(int i =1;i<=40;i++)
{
int pow_a=Pow(aa,i);
int pow_b=Pow(bb,i);
if(pow_a==ai && pow_b==bi)
return 1;
if(pow_a>ai || pow_b>bi)
break;
}
return 0;
}
int main()
{
int n;
long long temp,x[1001]={0};
scanf("%d",&n);
set<long long > set_x;
for(int i=0;i<n;i++)
{
scanf("%lld",&temp);
set_x.insert(temp);
}
n=0;
set<long long>::const_iterator iter_set;//常量迭代器
for(iter_set=set_x.begin();iter_set!=set_x.end();iter_set++)
{
x[n++]=*iter_set;
}
for(int i=0;i<n-1;i++)
{
long long gcd_res=gcd(x[i+1],x[i]);
a[i]=x[i+1]/gcd_res;
b[i]=x[i]/gcd_res;
}
for(int i=1;i<=40;i++)
{
float aa=pow(a[0],(double)1/i);
float bb=pow(b[0],(double)1/i);
if(aa-int(aa)<0.000001 && bb-int(bb)<0.000001)
{
int flag=0;//找到q的标志
for(int j=1;j<n-1;j++) // 对每个a[i]/b[i] 如果aa/bb都满足条件 则符合
if(!test(int(aa),int(bb),a[j],b[j]))
{
flag=1;// aa/bb不符合
break;
}
if(!flag)
{
printf("%d/%d\n",int(aa),int(bb));
break;
}
}
}
return 0;
}
- 利用了set的唯一性和有序性
- 对任意的a[i]/b[i] ,满足条件的q 必定存在 a[i]/b[i] =q^n (其中n越小q越大)
- 枚举所有可能的q,如何枚举?
因为a[i]/b[i] =q^n = a^n /b^n 可以发现枚举n就可以了,
i从1-40,如果a[i]和b[i]开i次方为整数,则是一个可能的Q,然后拿其余的a[i]/b[i]检验Q是否满足Q^j ==a[i]/b[i]
如果都满足,则输出并退出循环,此时的Q肯定最大,因为a[i]/b[i]是大于1的,一直开根的结果肯定越来越小,所以第一次得出的Q肯定是最大的