拼多多 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」!