2016年第七届蓝桥杯C/C++程序设计本科B组省赛 最大比例(编程大题)

2016年第七届蓝桥杯C/C++程序设计本科B组省赛题目汇总:

http://blog.csdn.net/u014552756/article/details/50946357


最大比例

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 <xxx>, 不能通过工程设置而省略常用头文件。

提交时,注意选择所期望的编译器类型。


思路:所有级别的奖金数构成了一个等比数列,公比相同。例如,

1  2  4  8  16  32这一个等比数列。

因为题意为随机调查一些获奖者的奖金数,即,抽到的项可能为连续的项也可能是不连续的项。

如果抽到1  2  4,这三个连续项,公比为4/2=2/1=2。

如果抽到1  4  8,这三个不连续的项,则相邻项的商为8/4=2, 4/1=4,再从4和2中取最大公约数就为最后的结果。相当于1为数列第一项,4为数列第三项,8为数列第四项,即1=a1  4=a1*r^2   8=a1*r^3,

8/4=r      4/1=r^2    从r和r^2中得到公比,即为最大的比例。

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

long long int a[100],p1[100],p2[100];

long long int gcd(long long int a,long long int b)
{
    long long int t;
    while(t=a%b)
    {
        a=b;
        b=t;
    }
    return b;
}

int main()
{
    int n;
    cin>>n;

    memset(a,0,sizeof(a));
    for(int i=0; i<n; i++)
    {
        cin>>a[i];
    }
    sort(a,a+n);//从小到大排序
    int k=1;
    for(int i=1; i<n; i++)//去掉重复的数字
    {
        if(a[i]!=a[i-1])
            a[k++]=a[i];
    }
    n=k;
    if(n==1)//如果只剩下一个数字,则公比为1/1
    {
        cout<<"1/1"<<endl;
        return 0;
    }
    else if(n==2)//如果剩下两个数字,则公比为两者的商,利用最大公约数求商
    {
        long long int g=gcd(a[n-1],a[n-2]);
        cout<<a[n-1]/g<<"/"<<a[n-2]/g<<endl;
    }
    else if(n>2)
    {
        k=0;
        long long int g,g1,g2;
        for(int i=1; i<n; i++)//分别求出后一项与前一项的比值
        {
            g=gcd(a[i],a[i-1]);
            p1[k]=a[i]/g;
            p2[k]=a[i-1]/g;
            k++;
        }
        double t=999999;
        long long int t1,t2,tt1,tt2;

        for(int i=0; i<k; i++)//遍历每一个比值,用大的除以小的,找出最小的公比
            for(int j=i+1; j<k; j++)
            {

                if(p1[i]*p2[j]>p1[j]*p2[i])
                {
                    t1=p1[i]/p1[j];
                    t2=p2[i]/p2[j];
                }
                else if(p1[i]*p2[j]<p1[j]*p2[i])
                {
                    t1=p1[j]/p1[i];
                    t2=p2[j]/p2[i];
                }
                else if(p1[i]*p2[j]==p1[j]*p2[i])
                {
                    t1=p1[i];
                    t2=p2[i];
                }
                if(1.0*t1/t2<t)
                {
                    t=1.0*t1/t2;
                    tt1=t1;
                    tt2=t2;
                }
            }
        g=gcd(tt1,tt2);
        cout<<tt1/g<<"/"<<tt2/g<<endl;
    }

    return 0;
}

你可能感兴趣的:(2016年第七届蓝桥杯C/C++程序设计本科B组省赛 最大比例(编程大题))