拼多多校招的三道笔试题

题目记不太清了,主要是存下代码

第一题

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <sstream>
#include <queue>
using namespace std;

struct compare
{
	bool operator()(int &a, int &b)
	{
		if ((a & 0x1) && !(b & 0x1))
			return true;
		else if (!(a & 0x1) && (b & 0x1))
			return false;
		else
		{
			if (a < b)
				return true;
			else
				return false;
		}
	}
};

int main()
{
	string s; int N;
	while (cin >> s)
	{
		for (auto &t : s)
			if (t == ',' || t == ';')
				t = ' ';
		istringstream input(s); vector<int> out;
		priority_queue<string, vector<int>, compare> m_queue;
		//最后一个就是N
		while (input >> N)
			m_queue.push(N);
		bool flag = false;
		for (int i = 0; i < N; i++)
		{
			if (!flag && m_queue.top() == N)
			{
				flag = true;
				i--;
				continue;
			}
			out.push_back(m_queue.top());
			m_queue.pop();
		}
		for (int i = 0; i < out.size() - 1; i++)
			cout << out[i] << ",";
		cout << out[out.size() - 1] << endl;
	}
	return 0;
}

第二题

/*
第二题:女朋友和男朋友玩纸牌,各抽n1 n2张牌,女朋友有三种策略:
d:丢弃手牌中最左边的牌
l:将手牌中最左边的牌放到新牌堆最左边
r:将手牌中最左边的牌放到新牌堆最右边。
求能使女朋友和男朋友纸牌顺序及顺序相同的策略。
示例:女朋友抽到三张牌,分别为:1 2 3,男朋友抽到一张牌,为:3
则策略为:d d l或者d d r

第二题是bfs,让每一次的操作为d l r,操作完N次看看形成的串是否等于男朋友的串,是就加入到答案,最后可能会有多个答案,对答案进行升序排序即可。
难点:女朋友的初始串等于男朋友的串,答案为“”,也算是一个答案。
*/

void dfsfind(set<string> &save, string path, int s, string news, string m, string &b)
{
	if (s == 0 && news == b)
	{
		save.insert(path);
		return;
	}
	if (s < 0 || m.size() < 1)
		return;
	dfsfind(save, path + "d", s - 1, news, m.substr(1), b);
	dfsfind(save, path + "l", s - 1, m[0] + news, m.substr(1), b);
	dfsfind(save, path + "r", s - 1, news + m[0], m.substr(1), b);
}

int main_pdd2()
{
	int s; string m, b;
	cin >> s;
	for (int i = 0; i < s; i++)
	{
		set<string> save;
		cin >> m >> b;
		dfsfind(save, string(), s, string(), m, b);
		cout << "{" << endl;
		for (auto &t : save)
			cout << t << endl;
		cout << "}" << endl;
	}
	return 0;
}

第三题

/*
几乎每一个人都用 乘法表。但是你能在乘法表中快速找到第k小的数字吗?

给定高度m 、宽度n 的一张 m * n的乘法表,以及正整数k,你需要返回表中第 k 小的数字。
*/

class Solution
{
public:
	//函数功能:获得在m*n的乘法表中,找出有多少个值 <= num。返回满足条件的值的数量
	int fun(int m, int n, int num)
	{
		int count = 0;
		for (int i = 1; i <= m; ++i) //行从第一行开始
		{
			count += min(num / i, n);//此表达式的含义:num在乘法表的第i行中,有多少个值小于或等于该值(<=num的个数)(这个除i简直神仙思想)
		}
		return count;
	}

	int findKthNumber(int m, int n, int k)
	{
		if (k == 1)
			return 1;
		if (k == m*n)
			return m*n;
		int lo = 1, hi = m*n, mi = 0;
		//跟普通二分不一样,普通二分把下标来当作边界,而这里的二分则是把值来当作边界
		while (lo < hi)
		{
			mi = (lo + hi) >> 1;
			int temp = fun(m, n, mi);
			if (temp < k)
				lo = mi + 1;
			else
				hi = mi;  //核心在于这里的收敛,不直接跳出
			//temp >= k, 在temp>k时,为什么不取 right = mid-1,而是right = mid。
			//因为我们的目标值可能存在重复,比如 123334,如果我选择要找第3小的数,而mid当前恰好=3,那么temp得到的结果会是5(<=mid)。
			//如果我们选择right = mid-1=2。那么将会运行错误导致结果错误。
			//在temp = k时,为什么不能立马返回结果呢,而是继续运行缩小边界?
			//因为我们当前的mid可能是一个不在乘法表中的值,毕竟mid=(left+right) >> 1; 所以立即返回可能返回错误答案。
			//所以一定收缩范围 直到left=right,最终返回的一定是正确值
			//(若答案t的temp = k, 而某一非表值x的temp也=k, 那么t一定比x小,最终x也会被right缩小导致出局)。
		}
		return lo;
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

方寸间沧海桑田

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值