第七届蓝桥杯C++B组:最大比例

版权声明:转载留名即可 ^_^ https://blog.csdn.net/qq_33375598/article/details/88594001

 

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

资源约定:
峰值内存消耗 < 256M
CPU消耗  < 3000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

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

#include <cstdio>
#include <vector>
#include<algorithm>
#include <iostream>
#include <map>
using namespace std;

typedef long long LL;
int n;
LL data[100];

struct Ratio{
    LL x, y;
    Ratio(LL _x, LL _y ): x(_x) , y(_y){
        LL _gcd = gcd(x,y);
        x /= _gcd;
        y /= _gcd;
    }
    LL gcd(LL a, LL b){
        if(b == 0) return  a;
        return gcd(b, a % b);
    }
};

vector<Ratio> radios;
map<LL ,map<LL,LL> > all_ex;//对all_ex[x][pow] == x开pow次方
map<LL ,map<LL,LL> > all_log;//all[x][y] == log_y_x,y的多少次方是x?
void init(){
    for (int i = 2; i < 1e6; ++i) {
        LL cur = (LL)i*i;
        int pow = 2;
        while(cur < 1e12){
            all_ex[cur][pow] = i;
            all_log[cur][i] = pow;
            pow++;
            cur *= i;
        }
    }
}

LL extract(LL x, LL pow){
    if(pow == 1) return x;
    if(x == 1) return 1;
    if(all_ex[x].find(pow) != all_ex[x].end())
        return all_ex[x][pow];
    else
        return  -1;
}

LL log(LL base, LL x){
    if(base == 1) return 1;
    if(all_log[x].find(base) !=  all_log[x].end())//意味着可以得开一个k,base的k次方是x
        return all_log[x][base];
        return -1;
}
int main(){
    init();
//处理输入
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) {
        scanf("%lld", &data[i]);
    }
//排序
    sort(data, data + n);
//处理只有两项特殊情况
    if(n == 2){
        Ratio ans = Ratio(data[1], data[0]);
        cout<<ans.x<<endl<<ans.y<<endl;
        return 0;
    }
//两两比值,以分数形式存储,存储到vector
    for (int j = 0; j < n - 1; ++j) {
        if(data[j + 1] != data[j])
            radios.push_back(Ratio(data[j + 1], data[j]));
    }
//对第一个比值开1~。。。pow(极限40)次方,作为基数,如果这个基数也是其他比值的基数的话,基数就是答案
    for (int pow = 1; pow <= 40; ++pow) {
        Ratio ra0 = radios[0];
        LL x = ra0.x;
        LL y = ra0.y;
        LL base_x = extract(x,pow); //对x开pow次方
        LL base_y = extract(y,pow);
        if(base_x == -1 || base_y == -1) continue;//开不出来,continue
// 能开,就要取确认所有比值的分子是fx的整数次方,所有比值的分母是fy的整数次方
//记px = getpow(xx,base_x),log_y = getpow(yy,base_y)要求必须是整数且px==log_y
        bool all_match = true;
        for (int i = 1; i < radios.size(); ++i) {
            LL xx = radios[i].x;
            LL yy = radios[i].y;
            LL log_x = log(base_x, xx);
            LL log_y = log(base_y, yy);
            if(base_y == 1 && yy == 1) log_y =log_x;
            if(log_x == -1 || log_y == -1 || log_x != log_y){
                all_match = false;
                break;
            }
        }
        if(all_match){
            Ratio ans = Ratio(base_x, base_y);
            cout<<ans.x<<endl<<ans.y<<endl;
            return 0;
        }
    }
    return 0;
}

 

猜你喜欢

转载自blog.csdn.net/qq_33375598/article/details/88594001
0条评论
添加一条新回复