2016京东校招-进制均值、幸运数字、爬山

进制均值

Description:
小明非常喜欢自然数,他发现自然数123用十六进制表示时只有两位,第一位是7 第二位是11,所以自然数123用十六进制表示时的 数码和 是18. 现在他想知道自然数n用2进制、3进制、4进制......n-1进制表示时所有的数码和加起来的平均值。计算数码和时采用的是十进制,最终的结果是不可约的分数。
输入有多组测试数据,每组测试数据占一行,为自然数n(3 <= n <= 1000),输入到文件结束。输出输出题目要求的结果,格式为 X/Y ,分子在前,分母在后。每个结果占一行。
样例输入
5
3
样例输出
7/3
2/1

这道题比较简单,首先借用一下任意进制转换的代码:

// n   :被转换的数字
// m  :代表m进制
// a[] :代表储存转换后数字的数组
while(n){
        a[k++] = n % m;
        n /= m;
}

要求和的话就需要做一些变动了。只需要令一个数字sum保存,然后将第二行代码改为 sum += n%m; 即可。
得到所有的数码位的和后,下一步就是求平均值了。这里要注意约分一下,因为 sum 不一定与分母互质。注意到从 2n-1 共有 n-2 个数,因此只需要用辗转相除法求得 sumn-2 的最大公约数,再输出 (sum/gcd) / ((n-2)/gcd) 即可。代码如下:

#include 
#include 
#include 
using namespace std;

int gcd(int m, int n)
{
    if(n==0)
        return m;
    else return gcd(n, m%n);
}

int main()
{
    int n;
    while(cin>>n){
        int sum = 0;
        for(int i=2; i

第k个幸运数字

Description:数字4和7是幸运数字,而其他的都不是幸运数字。一个整数是幸运数字,当且仅当它的十进制表示只包含幸运数字。

现在让你给出第K大的幸运数字。
Input
第一行一个整数K(1<=K<=10^18)
Output
第K大的幸运数字。

思路:把4看成二进制的0,7看成二进制的1,前面再补一个1,如下表:

k(dec) k+1(dec) bin(k+1) bin(k+1)抹去第一个1 num
1 2 10 0 4
2 3 11 1 7
3 4 100 00 44
4 5 101 01 47
5 6 110 10 74
6 7 111 11 77
7 8 1000 000 444
8 9 1001 001 447
9 10 1010 010 474

这个规律已经很明显了,我们不难写出代码:

#include 
#include 
#include 
#include 
#include 
using namespace std;

int main(){
    int T;
    long long k;
    int a[1000];
    scanf("%d", &T);
    while(T--){
        cin>>k;
        memset(a,0,sizeof(a));
        long long m = k+1;
        int n = 0;
        while(m){
            n++;
            m /= 2;
        }
        k = k+1;
        n--;
        cout<=0; i--){
            if(k%2 == 0)
                a[i] = 4;
            else
                a[i] = 7;
            k /= 2;
        }
        for(int i=0; i

爬山

题目描述:
小B曾经酷爱网络游戏,整日通宵达旦的玩游戏,导致身体素质急剧下降,因此下决心痛改前非,远离一切电子产品,并通过远足爬山的方式改变生活方式并提高身体素质。由于担心对身体造成太大的负荷,他总是选择最平坦的路径,并记录每天的行程情况及达到的最高海拔,使得连续两天之间的海拔之差最多为一个单位。不幸的是,在行程结束时,他不小心掉进河里,造成部分记录信息遗失。他想知道自己行程中可能达到的最高海拔,你是否能够帮忙?
输入
输入有若干组,每组的第一行为空格分隔的两个整数n和m,1<=n<=10^8, 1<=m<=10^5,分别表示行程天数以及未遗失的记录数。随后紧跟m行,每行为空格分隔的两个整数d和h,1<=d<=n, 0<=h<=10^8,表示行程的第几天及当天达到的最高海拔。
输出
对每组输入,如果记录是可能的,则在单独的行中输出可能达到的最高海拔,否则输出字符串“IMPOSSIBLE”(不含引号)。

样例输入
8 2
2 0
7 0
8 3
2 0
7 0
8 3
样例输出
2
IMPOSSIBLE

Hint
第一天和最后一天的海拔可以是任何值。

这道题逻辑比较难懂,但是耐心分析一番后,还是可以做出来的。已知天数 d1d2 ,以及这两天到达的海拔高度 h1h2,则这段时间上的最高高度为 (d2-d1)/2 + (h2+h1) 。若 h2-h1 > d2-d1 ,则不符题意,直接输出“IMPOSSIBLE”就好了。

经过以上推断,不难写出代码:

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

map mp;
vector vec;
int m, n;

int solve()
{
    int max_h = mp[vec[0]] + vec[0] - 1;
    for(int i=1; i vec[i] - vec[i-1]){
            cout<<"IMPOSSIBLE"< t ? max_h : t;
    }
    int end = mp[vec[m-1]] + n - vec[m-1];
    max_h = max_h > end ? max_h : end;
    cout<>n>>m){
        int d, h;
        for(int i=0; i>d>>h;
            mp[d] = h;
            vec.push_back(d);
        }
        sort(vec.begin(), vec.end());
        solve();
        mp.clear();
        vec.clear();
    }
    return 0;
}

代码可以随意取用,欢迎前来探讨或者给出错误样例~
陈政/arc001 原创作品转载请注明出处

你可能感兴趣的:(2016京东校招-进制均值、幸运数字、爬山)