• 征战蓝桥 —— 2016年第七届 —— C/C++A组第10题——最大比例


    题目

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

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

    代码

    #include <stdio.h>
    #include <iostream>
    #include <vector>
    #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> ratios;
    map<LL, map<LL,LL> > all_ex;//all_ex[x][pow]==x开pow次方
    map<LL, map<LL,LL> > all_log;//all_log[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;
            }
        }
    }
    /**
     * 对x开pow次方
     * @param x
     * @param pow
     * @return
     */
    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())//意味着x可以开pow整数次方
            return all_ex[x][pow];
        else
            return -1;
    }
    /**
     * 求log_base_x
     * @param base
     * @param x
     * @return
     */
    LL log(LL base,LL x){
        if(base==x)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(int argc, const char *argv[]) {
        init();
        freopen("/Users/zhengwei/CLionProjects/lanqiaobei2019/2016_C_A/data10/in8.txt","r",stdin);
    //处理输入
        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 << "/" << ans.y << endl;
            return 0;
        }
    //求两两比值,以分数形式存储,vector
        for (int i = 0; i < N - 1; ++i) {
            if (data[i + 1] != data[i])//去重
                ratios.push_back(Ratio(data[i + 1], data[i]));
        }
    //对第一个比值开1~..pow(极限为40).次方,作为基数,如果这个基数也是其他比值的基数的话,该基数就是答案
        for (int pow = 1; pow <= 40; ++pow) {
            Ratio ra0 = ratios[0];
            LL x = ra0.x;
            LL y = ra0.y;
            LL base_x = extract(x, pow);//对x开pow次方,作为基数,去尝试
            LL base_y = extract(y, pow);//对y开pow次方,作为基数,去尝试
            if (base_x == -1 || base_y == -1)continue;//开不出,continue
    //        能开:就要去确认所有比值的分子是fx的整数次方,所有比值的分母是fy的整数次方
    //计px=getPow(xx,base_x),py=getPow(yy,base_y),要求必须是整数且px==py
            bool all_match = true;
            for (int i = 1; i < ratios.size(); ++i) {
                LL xx = ratios[i].x;
                LL yy = ratios[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 << "/" << ans.y << endl;
                return 0;
            }
    
        }
        return 0;
    }
    
  • 相关阅读:
    C#网络编程(异步传输字符串)
    C#网络编程(同步传输字符串)
    C#网络编程(基本概念和操作)
    Asp.Net 构架(HttpModule 介绍)
    Asp.Net 构架(Http Handler 介绍)
    Asp.Net构架(Http请求处理流程)
    XML的应用 ---- 从一个范例看xml数据、xsd验证、xslt样式
    jQuery的ajax跨域实现
    常见26个jquery使用技巧详解
    常用Request对象获取请求信息
  • 原文地址:https://www.cnblogs.com/AlexKing007/p/12338691.html
Copyright © 2020-2023  润新知