网易2017运维工程师笔试题(程序题)——山寨题解

第一题

题意:某人想买n个苹果,水果摊只有6个一袋和8个一袋两种售卖方式,问是否能按袋买进正好凑足n个,如果可以,输出最少包数,不可以则输出-1。
题解:跟蓝桥杯初赛题目难度类似。排列问题,n规模很小,不超过100,深搜一下,每层递归保存剩余苹果数目,先尝试放8个,如果无解再尝试放6个,到某层如果剩余数目为0则满足条件,输出层数后返回。
代码:

#include 
#include 
#include 
#include 
using namespace std;
int _stack[100], top;
bool dfs(int rest, int k)
{
    if(rest < 0) return false;
    else if(rest == 0)
    {
        printf("%d\n", k);
        return true;
    }
    _stack[k] = 8;
    if(dfs(rest - 8, k + 1)) return true;
    _stack[k] = 6;
    if(dfs(rest - 6, k + 1)) return true;
    return false;
}
int main()
{
    int n;
    cin >> n;
    if(!dfs(n, 0)) printf("-1\n");
    return 0;
}

第二题

题意:给出圆的半径的平方(整数)n,求落在圆上的横纵坐标均为整数的点的数目。
题解:从0开始枚举横坐标点,平方后和n作差,判断纵坐标是否为平方数,如果是则计数。最终数乘以4就接近答案了(相当于枚举的是1/4圆上的点),需要注意的是横坐标轴上如果存在点则需要减去一次,不然会多出4。
代码:

#include 
#include 
#include 
#include 
using namespace std;
typedef long long lint;
const double eps = 1e-6;
int main()
{
    int r2, o = 0, e = 0;
    lint rst;
    cin >> r2;

    for(int i = 0, k; (lint)i * i <= (lint)r2; i++)
    {
        rst = (lint)r2 - (lint)i * i;
        k = int((sqrt(double(rst)) + eps));
        if((lint)k*k == rst)
        {
            //printf("%d %d\n", i, k);
            o++;
            if(!k) e++;
        }
    }
    cout << (o - e) * 4 << endl;
    return 0;
}

第三题

题意:给出一个整数n,求1到n所有数的最大奇数因子的和。
题解:这n个数可以按照含2因子的次数分类(不超过30类),用n / 2^i就可以求出含有2^i的最大奇数k,加上[1, k]内的奇数即可,由于是等差数列可以用公式算出。
代码:

#include 
#include 
using namespace std;
typedef long long lint;
int gg[50];
int main()
{
    for(int i = 0; i <= 30; i++)
        gg[i] = (1 << i);
    /// [gg[0], gg[30] ]
    int N;
    cin >> N;
    lint o = 0;
    for(int i = 0, j, k; i <= 30; i++)
    {
        j = N / gg[i];
        if(j == 0) continue;
        if(j % 2 == 0) j--;
        k = j / 2;
        o += ((lint)(1 + j) * j / 2) - (2 * (lint)(1 + k) * k / 2);
    }
    cout << o << endl;
    return 0;
}

你可能感兴趣的:(网易2017运维工程师笔试题(程序题)——山寨题解)