网易2017内推C++笔试题目

[编程题] 分苹果
n 只奶牛坐在一排,每个奶牛拥有 ai 个苹果,现在你要在它们之间转移苹果,使得最后所有奶牛拥有的苹果数

都相同,每一次,你只能从一只奶牛身上拿走恰好两个苹果到另一个奶牛上,问最少需要移动多少次可以平分苹

果,如果方案不存在输出 -1。 
输入描述:
每个输入包含一个测试用例。每个测试用例的第一行包含一个整数 n(1 <= n <= 100),接下来的一行包含 n 

个整数 ai(1 <= ai <= 100)。


输出描述:
输出一行表示最少需要移动多少次可以平分苹果,如果方案不存在则输出 -1。

输入例子:
4
7 15 9 5

输出例子:
3

#include 
#include 
#include 

using namespace std;

int main()
{
    int ret = 0;
    int n = 0;
    int num = 0;

    while( cin >> n )
    {
        vector<int> data;
        int cnt = 0;
        int sum = 0;

        for( int i = 0; i < n; i++ )
        {
            cin >> num;
            data.push_back(num);
            sum += num;
        }

        if( sum % n != 0 )
        {
            cout << "-1" << endl;
            continue;
        }

        int avg = sum / n;

        for( int i = 0; i < n; i++ )
        {
            if( data[i] == avg )
            {
                continue;
            }

            int dif = data[i] - avg > 0 ? data[i] - avg : avg - data[i];

            if( dif % 2 != 0 )
            {
                cnt = -1;
                break;
            }

            if( data[i] > avg )
            {
                cnt += dif / 2;
            }
        }

        cout << cnt << endl;
    }

    return ret;
}




[编程题] 星际穿越
航天飞行器是一项复杂而又精密的仪器,飞行器的损耗主要集中在发射和降落的过程,科学家根据实验数据估计

,如果在发射过程中,产生了 x 程度的损耗,那么在降落的过程中就会产生 x2 程度的损耗,如果飞船的总损耗

超过了它的耐久度,飞行器就会爆炸坠毁。问一艘耐久度为 h 的飞行器,假设在飞行过程中不产生损耗,那么为

了保证其可以安全的到达目的地,只考虑整数解,至多发射过程中可以承受多少程度的损耗? 
输入描述:
每个输入包含一个测试用例。每个测试用例包含一行一个整数 h (1 <= h <= 10^18)。


输出描述:
输出一行一个整数表示结果。

输入例子:
10

输出例子:
2



#include 
#include 
#include 
#include 

using namespace std;

int main()
{
    int ret = 0;

    unsigned long long h = 0;
    unsigned long long result = 0;
    unsigned long long high = 0;
    unsigned long long low = 0;

    while( cin >> h )
    {

        high = sqrt(h);
        low = 0;
        unsigned long long mid = ( low + high ) / 2;

        while( low <= high )
        {
            mid = ( low + high ) / 2;
            unsigned long long cur = mid + mid * mid;

            if( cur <= h && ( mid + 1 + ( mid + 1 ) * ( mid + 1 ) ) > h )
            {
                break;
            }
            else if( cur > h )
            {
                high = mid - 1;
            }
            else
            {
                low = mid + 1;
            }
        }

        cout << mid << endl;

    }

    return ret;
}


[编程题] 分田地
牛牛和 15 个朋友来玩打土豪分田地的游戏,牛牛决定让你来分田地,地主的田地可以看成是一个矩形,每个位

置有一个价值。分割田地的方法是横竖各切三刀,分成 16 份,作为领导干部,牛牛总是会选择其中总价值最小

的一份田地, 作为牛牛最好的朋友,你希望牛牛取得的田地的价值和尽可能大,你知道这个值最大可以是多少吗

? 
输入描述:
每个输入包含 1 个测试用例。每个测试用例的第一行包含两个整数 n 和 m(1 <= n, m <= 75),表示田地的大

小,接下来的 n 行,每行包含 m 个 0-9 之间的数字,表示每块位置的价值。


输出描述:
输出一行表示牛牛所能取得的最大的价值。

输入例子:
4 4
3332
3233
3332
2323

输出例子:
2


// 运行上面的例子正确,但是提交超时

#include 
#include 
#include 
#include 
#include 

using namespace std;

int main()
{
    int ret = 0;

    int x1 = 0; // 代表横方向三刀
    int x2 = 0;
    int x3 = 0;

    int y1 = 0; // 代表竖方向三刀
    int y2 = 0;
    int y3 = 0;

    int n = 0;
    int m = 0;

    while( cin >> n >> m )
    {
        vector< vector<int> > data( n, vector<int>(m) );

        for( int i = 0; i < n; i++ )
        {
            string str;
            cin >> str;
            int len = str.length();

            for( int j = 0; j < len; j++ )
            {
                data[i][j] = str[j] - '0';
            }

        }

        int minMax = -1;

        int maxX = n - 2;
        int maxY = m - 2;

        for( x1 = 0; x1 <= maxX; x1++ )
        {
            for( x2 = x1 + 1; x2 <= maxX; x2++ )
            {
                for( x3 = x2 + 1; x3 <= maxX; x3++ )
                {
                    for( y1 = 0; y1 <= maxY; y1++ )
                    {
                        for( y2 = y1 + 1; y2 <= maxY; y2++ )
                        {
                            for( y3 = y2 + 1; y3 <= maxY; y3++ )
                            {
                                vector< vector<int> > dataX;
                                vector< vector<int> > dataY;    

                                vector<int> tmp(2);
                                tmp[0] = 0;
                                tmp[1] = x1;
                                dataX.push_back(tmp);

                                tmp[0] = x1 + 1;
                                tmp[1] = x2;
                                dataX.push_back(tmp);

                                tmp[0] = x2 + 1;
                                tmp[1] = x3;
                                dataX.push_back(tmp);


                                tmp[0] = x3 + 1;
                                tmp[1] = n - 1;
                                dataX.push_back(tmp);


                                tmp[0] = 0;
                                tmp[1] = y1;
                                dataY.push_back(tmp);

                                tmp[0] = y1 + 1;
                                tmp[1] = y2;
                                dataY.push_back(tmp);

                                tmp[0] = y2 + 1;
                                tmp[1] = y3;
                                dataY.push_back(tmp);


                                tmp[0] = y3 + 1;
                                tmp[1] = m - 1;
                                dataY.push_back(tmp);

                                vector<int> save;

                                for( int i = 0; i < 4; i++ )
                                {
                                    for( int j = 0; j < 4; j++ 

)
                                    {
                                        int sum = 0;

                                        for( int k1 = 

dataX[i][0]; k1 <= dataX[i][1]; k1++ )
                                        {
                                            for( int k2 

= dataY[j][0]; k2 <= dataY[j][1]; k2++ )
                                            {
                                                sum 

+= data[k1][k2];
                                            }
                                        }

                                        save.push_back

(sum);
                                    }
                                }

                                sort( save.begin(), save.end() );

                                if( minMax < save[0] )
                                {
                                    minMax = save[0];
                                }


                            }
                        }
                    }
                }
            }
        }

        cout << minMax << endl;

    }

    return ret;
}


//运行通过解法
/*
二分答案,判断可行性时暴力枚举三列的情况,然后横着贪心地扫一遍,每当四个都满足时就砍一刀,满足四次

即可,复杂度O(N^4logN)
From: http://www.nowcoder.com/discuss/6967?type=1&order=0&pos=5&page=0


*/
#include 
#include 
#include 
#include 
using namespace std;
const int N = 10010;
char str[100];
int a[110][110];
int sum[110][110], n, m;
int calc(int x, int y, int i, int j)  // 求左上顶点(i,j)到右下顶点(x,y)确定的田地的价值和
{
    return sum[x][y] - sum[x][j] - sum[i][y] + sum[i][j];
}

bool judge(int x)
{
    for( int i = 1; i <= m - 3; i++ )
    {
        for( int j = i + 1; j <= m - 2; j++ )
        {
            for( int k = j + 1; k <= m - 1; k++ )
            {
                int last = 0, cnt = 0;

                for( int r = 1; r <= n; r++ )
                {
                    int s1 = calc( r, i, last, 0 );
                    int s2 = calc( r, j, last, i );
                    int s3 = calc( r, k, last, j );
                    int s4 = calc( r, m, last, k );

                    if( s1 >= x && s2 >= x && s3 >= x && s4 >= x )  // 当前横一

刀满足条件
                    {
                        last = r; cnt++;
                    }

                }

                if(cnt >= 4) //表明当前x是16块田地中最小的,返回true
                {
                    return true;
                }

            }
        }
    }

    return false;
}

int main()
{
    while(scanf("%d%d", &n, &m) > 0)
    {
        for(int i = 1; i <= n; i++)
        {
            scanf("%s", str + 1);
            for(int j = 1; j <= m; j++)
            {
                a[i][j] = str[j] - '0';
            }
        }

        memset(sum, 0, sizeof sum);

        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= m; j++)
            {
                sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + a

[i][j];
            }
        }

        // sum[i][j]表示坐标(i,j)左上方价值总和

        for( int i = 1; i <=n; i++ )
        {
            for( int j = 1; j <= m; j++ )
            {
                cout << sum[i][j] << ' ';
            }

            cout << endl;

        }


        int l = 0, r = sum[n][m], ans = 0;
        // sum[n][m]表示所有价值总和

        while(l <= r)
        {
            int m = (l + r) >> 1;

            if( judge(m) ) // 表明m是16块田地最小的
            {
                l = m + 1;
                ans = m;
            }
            else 
            {
                r = m - 1;
            }

        }

        printf("%d\n", ans);
    }
}

/*
4 4
3332
3233
3332
2323

3 6 9 11
6 11 17 22
9 17 26 33
11 22 33 43

2
*/

你可能感兴趣的:(笔试/面试)