拼多多 2019 春季算法实习生在线笔试

1. 题目一

给出两个数组,求两个数组对应元素乘积的最小值。

先对两个数组排序,然后用第一个数组的最大值和第二个数组的最小值相乘,依次遍历即可。

#include <iostream>
#include <stdio.h>
#include <vector>
#include <algorithm>

using namespace std;
bool ascend(int i, int j) {return (i < j);}
bool descend(int i, int j) {return (i > j);}

int main()
{
    int n = 0;
    scanf("%d", &n);

    vector<int> a;
    for (int i = 0; i < n; i++)
    {
        int temp = 0;
        scanf("%d", &temp);
        a.push_back(temp);
    }

    sort(a.begin(), a.end(), ascend); // a 升序排列

    vector<int> b;
    for (int i = 0; i < n; i++)
    {
        int temp = 0;
        scanf("%d", &temp);
        b.push_back(temp);
    }

    sort(b.begin(), b.end(), descend); // b 升序排列

    int sum = 0;
    for (int i = 0; i < n; i++)
    {
        sum += a[i] * b[i];
    }

    cout << sum;

    return 0;
}

2. 题目二

一套英文字母卡片序列,将重复字母剔除后字母序最小(不区分大小写)的序列中第一张卡片是哪个字母?

例:xaBXY 剔除重复字母后可以为 xaby 或者 abxy,其中字母序最小的为 abxy,第一张卡片为 a

第一次遍历,记录每个字母出现的位置,若多次出现,则保留最后面的位置。

第二次遍历,初始化 result 为 'z',如果访问到的元素小于 result 则更新之。一直向后遍历,直到访问到某个字母的位置与第一步记录的位置一样,则说明后面没有有重复字母,结束。


#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <map>

using namespace std;

#define N 52

int main()
{
    char data[N] = {'\0'};

    gets(data);
    int i = 0;
    map<int, char> pos;

    while (data[i] != '\0')
    {
        if (data[i] <= 'Z' && data[i] >= 'A') data[i] = data[i] + 32;
        int temp = data[i] - 'a';
        pos[temp] = i;
        i++;
    }

    char result = '\z';
    i = 0;
    while (data[i] != '\0')
    {
        int temp = data[i] - 'a';
        if (pos[temp] != i)
        {
            if (temp < int(result))
            {
                result = temp;
            }
        }
        else
        {
            if (temp < int(result))
            {
                result = temp;
            }
            break;
        }
        i++;
    }

    cout << char(result + 'a');

    return 0;
}

3. 题目三

银行抢劫问题。一个二维数组,第一维代表 n 个银行的位置,第二维代表每个银行可抢劫的金额,两个劫匪抢银行,要求银行距离大于 d,求可以抢劫的金额最大值。

按照金钱对银行进行排序,从后向前进行遍历,也即从可抢劫金额最大开始。如果两个银行的距离大于 d,更新结果。

如果某一次遍历发现当前两个相邻银行的金额之和比结果还要小,也就是前面所有的银行可抢劫额都比结果小,提前结束循环。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <algorithm>

using namespace std;

void Quick_Sort(int data[][2], int left, int right);

int main()
{
    int n = 0;
    int d = 0;
    scanf("%d %d", &n, &d);

    int data[n][2];

    for (int i = 0; i < n; i++)
    {
        scanf("%d %d", &data[i][0], &data[i][1]);
    }
    Quick_Sort(data, 0, n-1);

    int result = 0;
    for (int i = n-1; i >= 0; i--)
    {
        int max_sum_1 = 1;
        if (i > 1)  max_sum_1 = data[i][1] + data[i-1][1];
        if (max_sum_1 <= result) goto END;
        for (int j = i-1; j >= 0; j--)
        {
            int max_sum_2 = data[i][1] + data[j][1];
            if (abs(data[i][0] - data[j][0]) >= d)
                result = max(result, max_sum_2);
        }
    }

    END:    cout << result;
    return 0;
}

void Quick_Sort(int data[][2], int left, int right)
{
    if (left < right)
    {
        int pivot = data[left][1];
        int temp = data[left][0];
        int i = left;
        int j = right;
        while (i < j)
        {
            while (i < j && data[j][1] >= pivot)    j--;
            if (i < j)
            {
                data[i][0] = data[j][0];
                data[i++][1] = data[j][1];
            }
            while (i < j && data[i][1] <= pivot)    i++;
            if (i < j)
            {
                data[j][0] = data[i][0];
                data[j--][1] = data[i][1];
            }
        }
        data[i][1] = pivot;
        data[i][0] = temp;
        Quick_Sort(data, left, i-1);
        Quick_Sort(data, i+1, right);
    }
}

4. 题目四

给出两个由圆括号组成的字符串,交错这两个圆括号序列,但要保持每个字符在源字符串中的位置,问总共有多少种交错方式可以得到合法的圆括号表达式。

回溯法。遍历所有情况,当两个字符串都结束时查看生成的表达式是否合法。程序正确性待检验,笔试后自己线下总结的。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <stack>


using namespace std;
void Find(string &s, unsigned int i, string &t, unsigned int j, string result);
long long int num = 0;
long long int  N = 1e9 + 7;

int main()
{
    string s;
    string t;
    cin >> s >> t;

    string result;

    Find(s, 0, t, 0, result);

    num = num % N;
    cout << num << endl;

    return 0;
}

bool Is_Valid(string s)
{
    unsigned int i = 0;
    stack<char> bracket;
    while (i < s.size())
    {
        if (s[i] == '(')
        {
            bracket.push(s[i]);
        }
        else
        {
            if (bracket.empty())    return false;
            char temp = bracket.top();
            if (temp == '(')
            {
                bracket.pop();
            }
            else
            {
                return false;
            }
        }
        i++;
    }
    if (bracket.empty())    return true;
    else return false;
}

void Find(string &s, unsigned int i, string &t, unsigned int j, string result)
{
    if (i == s.size() && j == t.size())
    {
        if (Is_Valid(result))
        {
            num++;
            return;
        }
    }
    else if ((i < s.size() && j < t.size()))
    {
        string temp(result);
        result.push_back(s[i]);
        Find(s, i+1, t, j, result);
        temp.push_back(t[j]);
        Find(s, i, t, j+1, temp);
    }
    else if ((i < s.size() && j == t.size()))
    {
        result.push_back(s[i]);
        Find(s, i+1, t, j, result);
    }
    else //if ((i == s.size() && j < t.size()))
    {
        result.push_back(t[j]);
        Find(s, i, t, j+1, result);
    }
}

获取更多精彩,请关注「seniusen」!

posted @ 2019-03-23 20:49  seniusen  阅读(355)  评论(0编辑  收藏  举报