2016年蓝桥杯A组 第十题 最大比例

比赛时,当我看到这道题,我彻底的懵比了,没有思路,没有思路,没有思路,重要的事说三遍,赛后,也没有在网上找别人的代码看,因为对省赛感觉很不好,以为自己挂了,所以没有心情去看题,应该说是不敢去看题,成与败,关系着我的尊严,当初学校不让我报名A组,很多人都嘲讽我不知天高地厚,一个破二本的院校,还想挑战A组;更有人反问我,你才学了几天,到你比赛时撑死了也就学满七个月,就这么瞧不起B组?
实话说,我真的瞧不起B组,因为我相信自己的能力!

废话不多说,转入正题,对于这个题,我真的是没有一丝的思路可言,前天我百度了一下,网上还没有一个这道题相关的问题答案解析,没有办法,只能靠自己了,毕竟自己动手丰衣足食嘛。

先上题:

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

现在,我们随机调查了一些获奖者的奖金数。
请你据此推算可能的最大的等比值。

输入格式:
第一行为数字N,表示接下的一行包含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 , 不能通过工程设置而省略常用头文件。

苦于没有思路,苦于网上没有提示,只能自己想,最后,在一张废纸上找起了规律,结果发现真的毫无规律可言,只能作罢,用最朴素的办法解吧!

逆向思维考虑,需要求最大比例,那么肯定要从比例入手,所以首先就是求出所有的比例,并且去重,然后就需要对这些比例进行排序来谋求最大的基数,这个基数即为最大的比例。

思路听着很简单,但是实现起来着实麻烦,需要考虑的细节问题贼多,不多说了,看代码吧,代码更有说服力!

代码C:

#include 
#include 
#define _MAX 1000000000000

int N, p = 0;
long long M[100], nAtor[100], dAtor[100];
double W[100];

//M原数据排序去重
void sequenceM()
{
    int len = N, i , j;
    for (i = 0; i < N - 1; i++)
    {
        for (j = i + 1; j < N; j++)
        {
            if (M[i] > M[j])
            {
                M[i] ^= M[j];
                M[j] ^= M[i];
                M[i] ^= M[j];
            }
            else if (M[i] == M[j])
            {
                M[j] = _MAX;
                len--;
            }
        }
    }
    N = len;
//    for (i = 0; i < N; i++)
//    {
//        printf("%lld ", M[i]);
//    }
//    printf("\n");
    return ;
}

//约分
void reduce(int i)
{
    long long j = M[i];
    for (; j > 0; j--)
    {
        if (M[i] % j == 0 && M[i + 1] % j == 0)
        {
            dAtor[i] = M[i] / j;
            nAtor[i] = M[i + 1] / j;
            return ;
        }
    }
    return ;
}

//W数据排序去重
void sequenceW()
{
    int len = N - 1, i , j;
    for (i = 0; i < N - 2; i++)
    {
        for (j = i + 1; j < N - 1; j++)
        {
            if (W[i] > W[j])
            {
                double tempW = W[i];
                W[i] = W[j];
                W[j] = tempW;
                long long tempN = nAtor[i];
                nAtor[i] = nAtor[j];
                nAtor[j] = tempN;
                long long tempD = dAtor[i];
                dAtor[i] = dAtor[j];
                dAtor[j] = tempD;
            }
            else if (W[i] == W[j])
            {
                W[j] = _MAX;
                len--;
            }
        }
    }
    N = len;
//    for (i = 0; i < N; i++)
//    {
//        printf("%g %lld %lld\n", W[i], nAtor[i], dAtor[i]);
//    }
    return ;
}

//分别求分子、分母基数
long long NDbase(long long *Ator)
{
    long long flag = Ator[0];
    if (N == 1)
    {
        return flag;
    }
    int i = 1, j, tag = 0;  //标记flag是否为符合基数要求
    for (; i < N; i++)
    {
        for (j = 2; pow((double)flag, (double)j) <= Ator[i]; j++)
        {
            if (pow((double)flag, (double)j) == Ator[i])
            {
                tag = 1;
                break;
            }
        }
        if (tag == 1)
        {
            tag = 0;
            continue;
        }
        break;
    }
    if (i == N)
    {
        return flag;
    }
    tag = 0;
    for (flag = Ator[0] / 2; flag > 0; flag--)
    {
        for (i = 0; i < N; i++)
        {
            for (j = 2; pow((double)flag, (double)j) <= Ator[i]; j++)
            {
                if (pow((double)flag, (double)j) == Ator[i])
                {
                    tag = 1;
                    break;
                }
            }
            if (tag == 1)
            {
                tag = 0;
                continue;
            }
            break;
        }
        if (i == N)
        {
            return flag;
        }
    }
    return 0;
}

//求最大基数
void base()
{
    long long N, D;   //最大比例的分子和分母
    N = NDbase(nAtor);
    D = NDbase(dAtor);
    printf("%lld/%lld\n", N, D);
    return ;
}
//求最大比例
void pro()
{
    int i;
    sequenceM();
    for (i = 0; i < N - 1; i++)
    {
        W[i] = M[i + 1] * 1.0 / M[i];
        reduce(i);
    }
    sequenceW();
    base();
    return ;
}

int main(int argc, const char * argv[])
{
    int i = 0;
    scanf("%d", &N);
    for (; i < N; i++)
    {
        scanf("%lld", &M[i]);
    }
    pro();
    return 0;
}

是不是很长啊?不要急,慢慢看吧,注释我也写了,希望你能懂!真不懂的话,就别看了,去做别的题吧!做这个题是在浪费时间,对很多人而言……

OVER!!!

你可能感兴趣的:(数学相关,其他,最大比例,蓝桥杯,繁琐题)