网易2017秋招编程题集合

(一)如果一个数字序列逆置之后跟原序列是一样的就称这样的数字序列为回文序列。例如:
{1, 2, 1}, {15, 78, 78, 15} , {112} 是回文序列, 
{1, 2, 2}, {15, 78, 87, 51} ,{112, 2, 11} 不是回文序列。
现在给出一个数字序列,允许使用一种转换操作:
选择任意两个相邻的数,然后从序列移除这两个数,并用这两个数字的和插入到这两个数之前的位置(只插入一个和)。

现在对于所给序列要求出最少需要多少次操作可以将其变成回文序列。

//利用递归,两端不论怎样都要相等或者最终合成为同一个数
#include <iostream>
using namespace std;
int comb(int* nums, int head, int tail) {
    int times = 0;
    int left = nums[head], right = nums[tail];
    while (head < tail && left != right) {
        if (left < right) left += nums[++head], times++;
        else right += nums[--tail], times++;
    }
    if (head >= tail) return times;
    else return times += comb(nums, ++head, --tail);
}
int main(){
    int n = 0;
    int nums[50] = {0};
    cin >> n;
    for( int i = 0; i < n; i++)
        cin >> nums[i];
    cout << comb(nums, 0, n-1);
}
(二)小易有一个圆心在坐标原点的圆,小易知道圆的半径的平方。小易认为在圆上的点而且横纵坐标都是整数的点是优雅的,小易现在想寻找一个算法计算出优雅的点的个数,请你来帮帮他。
例如:半径的平方如果为25
优雅的点就有:(+/-3, +/-4), (+/-4, +/-3), (0, +/-5) (+/-5, 0),一共12个点。

#include<stdio.h>
#include<math.h>
int main(){
    int num,r,i,j,count=0;
    scanf("%d",&num);
    r=(int)sqrt(num);
    if(r*r==num){
       for(i=1;i<r;i++){
        for(j=r-i+1;j<r;j++){
            if(i*i+j*j==num){
                count++;
            }
        }
    }
    printf("%d",4*count+4);
    }else{
        for(i=1;i<=r;i++){
            double n=sqrt(num-i*i);
            j=(int)n;
            if(j==n)
                count++;
        }
        printf("%d",4*count);
    }
    return 0;
}

(三)小易来到了一条石板路前,每块石板上从1挨着编号为:1、2、3.......
这条石板路要根据特殊的规则才能前进:对于小易当前所在的编号为K的 石板,小易单次只能往前跳K的一个约数(不含1和K)步,即跳到K+X(X为K的一个非1和本身的约数)的位置。 小易当前处在编号为N的石板,他想跳到编号恰好为M的石板去,小易想知道最少需要跳跃几次可以到达。
例如:
N = 4,M = 24:
4->6->8->12->18->24
于是小易最少需要跳跃5次,就可以从4号石板跳到24号石板

#include<iostream> 
#include<vector> 
#include<math.h> 
   
using namespace std; 
void calYueshu(int n,vector<int> &yueshu); 
       
int main() 
{ 
    int N,M; 
    cin>>N>>M; 
    vector<int> steps(M+1,0); 
    steps[N]=1; 
       
    for(int i=N;i<=M;++i){ 
        if(steps[i]==0)continue;   //位置无法到达,跳过 
        vector<int> yueshu; 
        calYueshu(i,yueshu); 
        for(int j=0;j<yueshu.size();++j){  //记录从起点N到位置i的最小步数 
            if(yueshu[j]+i<=M){ 
                if(steps[yueshu[j]+i]==0)    //到达位置i的最小步数加1 
                    steps[yueshu[j]+i]=steps[i]+1; 
                else                         //其它点也能到达,比较大小,记录最小步数 
                    steps[yueshu[j]+i]=(steps[i]+1)<steps[yueshu[j]+i]?(steps[i]+1):steps[yueshu[j]+i]; 
            } 
        }   
    } 
       
    if(steps[M]==0) 
        cout<<-1<<endl; 
    else 
        cout<<steps[M]-1<<endl; 
    return 0;    
} 
   
//求约数 
void calYueshu(int n,vector<int> &yueshu){ 
    for(int i=2;i<=sqrt(n);++i){ 
        if(n%i==0){ 
            yueshu.push_back(i); 
            if(n/i != i) 
                yueshu.push_back(n/i); 
        }    
    }          
}


(四)一个只包含'A'、'B'和'C'的字符串,如果存在某一段长度为3的连续子串中恰好'A'、'B'和'C'各有一个,那么这个字符串就是纯净的,否则这个字符串就是暗黑的。例如:
BAACAACCBAAA 连续子串"CBA"中包含了'A','B','C'各一个,所以是纯净的字符串
AABBCCAABB 不存在一个长度为3的连续子串包含'A','B','C',所以是暗黑的字符串
你的任务就是计算出长度为n的字符串(只包含'A'、'B'和'C'),有多少个是暗黑的字符串。

#include<iostream>
using namespace std;
//主要是推导公式:
//例如:在字符串BAA的后面只能有两种添加字符的方法
//1.添加和末尾相同的字符变成BAAA,一定不是暗黑的字符串
//2.添加和末尾不同的字符串变成BAAB或BAAC,一定不是暗黑字符串
//用dp[0]和dp[1]分别表示上一次的添加方式对应的暗黑字符串的个数
//所以公式为:dp[0] = temp0 + temp1; dp[1] = 2*temp0 + temp1;
long long blackNum(int n){
    if(n == 1)return 3;
    if(n == 2)return 9;
    long long dp[2];
    dp[0] = 3;
    dp[1] = 6;
    for(int i = 2;i<n;i++){
        long long temp0 = dp[0];
        long long temp1 = dp[1];
        dp[0] = temp0 + temp1;
        dp[1] = 2*temp0 + temp1;
    }
    return dp[0]+dp[1];
}
int main(){
    int n;
    while(cin>>n){
        cout<<blackNum(n)<<endl;
    }
    return 0;
}

(五)对于一个整数X,定义操作rev(X)为将X按数位翻转过来,并且去除掉前导0。例如:
如果 X = 123,则rev(X) = 321;
如果 X = 100,则rev(X) = 1.
现在给出整数x和y,要求rev(rev(x) + rev(y))为多少?

#include <iostream>
using namespace std;
int reverseInt(int x){
    int ret=0;
    while(x){
        ret*=10;
        ret+=x%10;
        x/=10;
    }
    return ret;
}
int main(){
    int x,y;
    while(cin>>x>>y){
        cout<<reverseInt(reverseInt(x)+reverseInt(y))<<endl;
    }
    return 0;
}

(六)小易是一个数论爱好者,并且对于一个数的奇数约数十分感兴趣。一天小易遇到这样一个问题: 定义函数f(x)为x最大的奇数约数,x为正整数。 例如:f(44) = 11.
现在给出一个N,需要求出 f(1) + f(2) + f(3).......f(N)
例如: N = 7 
f(1) + f(2) + f(3) + f(4) + f(5) + f(6) + f(7) = 1 + 1 + 3 + 1 + 5 + 3 + 7 = 21
小易计算这个问题遇到了困难,需要你来设计一个算法帮助他。

#include<iostream>
using namespace std;
long long sum(long long n) {
    long long result = 0;
    while (n > 0) {
        if (n % 2 == 0) {
            result += n * n / 4;
            n /= 2;
        }
        else {
            result += n;
            n--;
        }
    }
    return result;
}
int main() {
    long long N;
    cin >> N;
    cout << sum(N) << endl;
}

(七)小易去附近的商店买苹果,奸诈的商贩使用了捆绑交易,只提供6个每袋和8个每袋的包装(包装不可拆分)。 可是小易现在只想购买恰好n个苹果,小易想购买尽量少的袋数方便携带。如果不能购买恰好n个苹果,小易将不会购买。

#include<iostream>
#include<math.h>
 
using namespace std;
 
 
int dsp(int n,bool &hasresult){
    if(n==0){
        hasresult = true;
        return 0;
    }
 
    else if(n<0){
 
        return 0;
    }
    return min(dsp(n-6,hasresult),dsp(n-8,hasresult))+1;
 
}
 
 
int main(){
    int n;
    cin>>n;
    bool hasresult = false;
    int cnt = dsp(n,hasresult);
    if(hasresult)
        cout<<cnt<<endl;
    else
        cout<<-1<<endl;
}


(八)A,B,C三个人是好朋友,每个人手里都有一些糖果,我们不知道他们每个人手上具体有多少个糖果,但是我们知道以下的信息:
A - B, B - C, A + B, B + C. 这四个数值.每个字母代表每个人所拥有的糖果数.
现在需要通过这四个数值计算出每个人手里有多少个糖果,即A,B,C。这里保证最多只有一组整数A,B,C满足所有题设条件。

#include<iostream>
using namespace std;
  
int main()
{   int a, b, c, d;
    int A, B, C;
    while(cin>>a>>b>>c>>d)
    {
        A=(a+c)/2;
        B=(b+d)/2;
        C=(d-b)/2;
        if(A-B==a && B-C==b && A+B==c && B+C==d)
        {
            cout<<A<<" "<<B<<" "<<C<<endl;
        }
        else
        {
            cout<<"No"<<endl;
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值