京东2017秋招笔试真题

京东2017秋招笔试真题

1. 进制均值

        尽管是一个CS专业的学生,小B的数学基础很好并对数值计算有着特别的兴趣,喜欢用计算机程序来解决数学问题。现在,她正在玩一个数值变换的游戏。她发现计算机中经常用不同的进制表示同一个数,如十进制数123表达为16进制时只包含两位数7、11(B),用八进制表示时为三位数1、7、3。按不同进制表达时,各个位数的和也不同,如上述例子中十六进制和八进制中各位数的和分别是18和11。
        小B感兴趣的是,一个数A如果按2到A-1进制表达时,各个位数之和的均值是多少?她希望你能帮她解决这个问题?
        所有的计算均基于十进制进行,结果也用十进制表示为不可约简的分数形式。

输入
输入中有多组测试数据。每组测试数据为一个整数A(1=<A=<5000)。 

输出
对每组测试数据,在单独的行中以X/Y的形式输出结果。 

样例输入 

3

样例输出 
7/3 
2/1

时间限制
C/C++语言:1000MS其它语言:3000MS 
内存限制 
C/C++语言:65536KB其它语言:589824KB

【分析】求数A的2~A-1(共A-2)个进制的进制数各位数字之和sum,X=sum,Y=A-2。注意最后对求出的分数约分。

#include <stdio.h>
int A;
int gcd(int a,int b)
{
    if(b==0)
        return a;
    return gcd(b,a%b);
}
int main()
{
    int i;
    int sum,temp;
    int factor;
    while(scanf("%d",&A)!=EOF)
    {
        sum=0;
        for(i=2;i<A;i++)  //枚举 A-2 个进制
        {
            temp=A;
            while(temp)   //除i取余,乘i取整
            {
                sum+=(temp%i);
                temp/=i;
            }
        }
        factor=gcd(sum,A-2);   //注意对结果约分
        printf("%d/%d\n",sum/factor,(A-2)/factor);
    }
    return 0;
}
2. 集合

给你两个集合,要求 {A} + {B}。
注:同一个集合中不会有两个相同的元素。

输入
多组(不超过 5 组)数据。
每组输入数据分为三行,第一行有两个数字 n,m(0<n,m<10000),分别表示集合 A 和集合 B 的元素个数。后两行分别表示集合 A 和集合 B。每个元素为不超出 int 范围的整数,每个元素之间有一个空格隔开。

输出
针对每组数据输出一行数据,表示合并后的集合,要求从小到大输出,每个元素之间有一个空格隔开。

样例输入
1 2
1
2 3
1 2
1
1 2

样例输出
1 2 3
1 2

时间限制
C/C++语言:1000MS其它语言:3000MS
内存限制
C/C++语言:65536KB其它语言:589824KB

【分析】并集运算。通过STL set实现。

#include <iostream>
#include <cstdio>
#include <set>
using namespace std;
const int maxn=10005;
int n,m;
int A[maxn],B[maxn];
int main()
{
    int i;
    int first;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        set<int> st;
        for(i=0;i<n;i++)
        {
            scanf("%d",&A[i]);
            st.insert(A[i]);
        }
        for(i=0;i<m;i++)
        {
            scanf("%d",&B[i]);
            st.insert(B[i]);
        }
        first=1;
        for(set<int>::iterator p=st.begin();p!=st.end();p++)
        {
            if(first==1)
            {
                printf("%d",*p);
                first=0;
            }
            else
                printf(" %d",*p);
        }
        printf("\n");
    }
    return 0;
}
3. 通过考试

        小明同学要参加一场考试,考试一共有n道题目,小明必须做对至少60%的题目才能通过考试。考试结束后,小明估算出每题做对的概率,p1,p2,…,pn。你能帮他算出他通过考试的概率吗? 

输入 
输入第一行一个数n(1<=n<=100),表示题目的个数。第二行n个整数,p1,p2,…,pn。表示小明有pi%的概率做对第i题。(0<=pi<=100) 

输出 
小明通过考试的概率,最后结果四舍五入,保留小数点后五位。 

样例输入 

50 50 50 50 

样例输出 
0.31250 

时间限制 
C/C++语言:1000MS其它语言:3000MS 
内存限制 
C/C++语言:65536KB其它语言:589824KB

【分析】DP。

        假设dp[i][j]表示i道题,答对j道题的概率,与子问题的递推关系如下公式:前i-1已经答对j道,第i道题为答错;前i-1答对j-1道题,第i道题答对。 即:

        dp[i][j]=dp[i-1][j]*(1-p[i])+dp[i-1][j-1]*p[i]; 

        注意初始条件:上公式中i, j从1开始。初始条件的设置:dp[0][0]=1;  dp[i][0]=dp[i-1][0]*(1-p[i]);

#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=105;
int n,p[maxn];
double dp[maxn][maxn]; //dp[i][j]表示前i个题目做对j个的概率,挨着dp即可
int main()
{
    int i,j;
    int right;      //小明通过考试至少需要做对的题数
    double temp,ans;//ans记录小明通过考试的概率
    scanf("%d",&n);
    for(i=1;i<=n;i++)
        scanf("%d",&p[i]);
    dp[0][0]=1;
    for(i=1;i<=n;i++)
    {   //初始化:前i道题均不对的概率=前i-1道题均不对的概率*第i道题不对的概率
        dp[i][0]=dp[i-1][0]*(100-p[i])/100;
        for(j=1;j<=i;j++)  //前i道题对j道(1<=j<=i)的概率=前i-1题对j-1题 第i题对的概率+前i-1题对j题 第i题不对的概率
            dp[i][j]=dp[i-1][j-1]*(100-p[i])/100 + dp[i-1][j]*1.0*p[i]/100;
    }
    temp=n*0.6;
    if((temp-(int)temp)!=0)   //进一法,求right
        right=(int)temp+1;
    else
        right=(int)temp;
    for(i=right;i<=n;i++)
        ans+=dp[n][i];
    printf("%.5lf\n",ans);
    return 0;
}
4. 异或

        异或运算是常见的二进制运算,给出两个n位二进制数a,b。a异或b的运算依次考虑二进制的每一位,若这一位相同,那么这一位的异或结果就是0,不同就是1。
        例如a=1100, b=0100。执行a异或b的运算,a的最高位是1,b的最高位是0,两个数字不同所以最高位异或结果是1;a和b次高位都是1,所以次高位异或为0;最后两位它们都是0,所以异或结果也都是0。那么a异或b的答案就是1000。
        现在输入两个n位二进制数,输出它们异或结果的十进制答案。上述样例中异或的二进制结果为1000,转化成十进制就是8。

输入
输入有三行,第一行一个数n(1<=n<=20),接下来两行有两个n位二进制数。输入的二进制数可能有前导零。

输出
输出一个数,异或结果的十进制数值,不要输出前导零。 

样例输入
4
1100
0100

样例输出
8

【分析】异或定义+进制转换思想。

#include <stdio.h>
int n;
char a[25],b[25],ret[25];  //ret保存异或结果串
int mypow(int a,int x)
{
    int i,ans=1;
    for(i=1;i<=x;i++)
        ans*=a;
    return ans;
}
int main()
{
    int i,sum;
    scanf("%d",&n);
    scanf("%s",a);
    scanf("%s",b);
    for(i=0;i<n;i++)
        ret[i]=((a[i]==b[i])?'0':'1');
    sum=0;
    for(i=0;i<n;i++)    //2进制转10进制,然后输出即可
        sum+=((ret[i]-'0')*mypow(2,n-1-i));
    printf("%d\n",sum);
    return 0;
}
5. 拍卖产品

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=1000005;
int n,m;
int V[maxn];
int main()
{
    int i;
    int ans=0,pos;
    scanf("%d %d",&n,&m);
    for(i=0;i<m;i++)
        scanf("%d",&V[i]);
    sort(V,V+m);     //对客户出价递增排序
    for(i=0;i<m;i++)
    {
        if(ans<V[i]*min(n-1,m-i))
        {
            ans=V[i]*min(n-1,m-i);
            pos=V[i];
        }
    }
    printf("%d\n",pos);
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值