携程笔试 5.7 研发方向1 专业笔试(二)讨论

三道编程题 63+90+89,没有一道题ac有点难受...

第一题爬楼梯plus版
不知道为什么只有63分!!!
#include <iostream>
#include <vector>
using namespace std;

int climb(int n) {
	if (n <= 0) return -1;

	vector<vector<int>> dp(n+1);
	for (int i = 0; i <= n; i++) dp[i].resize(2);

	dp[1][0] = dp[1][1] = 1;
	dp[2][0] = dp[2][1] = 2;
	dp[3][0] = 3;
	dp[3][1] = 4;
	
	for (int i = 4; i <= n; i++) {
		dp[i][0] = dp[i - 1][0] + dp[i - 2][0];
		dp[i][1] = dp[i - 1][1] + dp[i - 2][1] + dp[i - 3][0];
	}

	return dp[n][1];
}

int main() {
	int n;
	cin >> n;
	cout << climb(n) << endl;
	return 0;
}

第二题
一道图论题,求给定两点的所有路径的题,dfs解决,注意读入数据的时候要建立地名和编号的双向映射关系
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;

const int MAXN = 30;
int G[MAXN][MAXN];
map<char, int> nameToIdx;
map<int, char> idxToName;
int N = 0;

vector<vector<int>> ans;
vector<int> path;
vector<bool> vis(MAXN);
int st, ed;

void dfs(int u) {
	vis[u] = true;
	path.push_back(u);
	if (u == ed) {
		ans.push_back(path);
	} else {
		for (int v = 0; v < N; v++) {
			if (G[u][v] && vis[v] == false) {
				dfs(v);
			}
		}

	}
	path.pop_back();
	vis[u] = false;
}

int convertNameToIndex(char name) {
	if (!('A' <= name && name <= 'Z')) {
		cout << "EMPTY" << endl;
		exit(0);
	}
	auto it = nameToIdx.find(name);
	if (it != nameToIdx.end()) {
		return it->second;
	} else {
		nameToIdx[name] = N;
		idxToName[N] = name;
		return N++;
	}
}

int main() {
	//freopen("input.txt", "r", stdin);
	string str;
	cin >> str;
	for (int i = 0; i < str.length(); i += 6) {
		char st = str[i + 1];
		char ed = str[i + 3];
		int u = convertNameToIndex(st);
		int v = convertNameToIndex(ed);
		G[u][v] = 1;
	}

	if (nameToIdx.count('A') == 0 || nameToIdx.count('B') == 0) {
		cout << "EMPTY" << endl;
		return 0;
	}

	st = nameToIdx['A'];
	ed = nameToIdx['B'];

	dfs(st);

	if (ans.size() == 0) {
		cout << "EMPTY" << endl;
		return 0;
	}

	sort(ans.begin(), ans.end(), [](const vector<int> &A, const vector<int> &B) {
		return A.size() < B.size();
		});

	cout << "[";
	for (int i = 0; i < ans.size(); i++) {
		if (i > 0) cout << ",";
		cout << "[";
		for (int j = 0; j < ans[i].size(); j++) {
			if (j > 0) cout << ",";
			cout << idxToName[ans[i][j]];
		}
		cout << "]";
	}
	cout << "]";
	cout << endl;
	return 0;
}
第三题
将一个数组划分成M部分,要求每一部分子数组的sum不能重复,求有多少种方案
我用dfs枚举所有可能的方案,再逐一判断,注意这里对区间求和是可以优化的。
#include <iostream>
#include <vector>
#include <set>
using namespace std;

int N, M;
vector<int> A;
vector<int> SUM;    // sum[i]表示数组前i个数字的和

vector<int> plan;

int cnt;

bool judge(vector<int> &plan) {
	set<int> S;
	int preCnt = 0;
	for (int x : plan) {
		int sum = SUM[preCnt + x] - SUM[preCnt];
		if (S.count(sum) > 0) return false;
		S.insert(sum);
		preCnt += x;
	}
	return true;
}

void dfs(int N, int M) {
	if (M == 0) {
		if (N == 0) {
			if (judge(plan)) {
				cnt++;
			}
		}
	} else {
		for (int i = 1; i <= N; i++) {
			plan.push_back(i);
			dfs(N - i, M - 1);
			plan.pop_back();
		}
	}
}

int main() {
	//freopen("input.txt", "r", stdin);
	cin >> N;
	A.resize(N);
	for (int i = 0; i < N; i++) {
		cin >> A[i];
	}
	cin >> M;
	if (N < M) {
		cout << "0" << endl;
		return 0;
	}
	SUM.resize(N + 1);
	for (int i = 1; i <= N; i++) {
		SUM[i] = SUM[i - 1] + A[i - 1];
	}
	dfs(N, M);
	cout << cnt << endl;
	return 0;
}


#携程##笔试题目#
全部评论
三道题全要求java,c,cpp,直接劝退了
2 回复
分享
发布于 2020-05-07 15:21
第一道题,把int类型改成long就行了,我java就是这样做的
点赞 回复
分享
发布于 2020-05-07 12:16
联想
校招火热招聘中
官网直投
int会有有溢出
点赞 回复
分享
发布于 2020-05-07 12:17
第一题的解法没有理解,楼主方便给解释一下吗?
点赞 回复
分享
发布于 2020-05-07 14:50
我做的後面两道题,居然不给用Python…分割数组也没做出来
点赞 回复
分享
发布于 2020-05-07 15:20
请问楼主第二道题要怎么让路线按长度排序?
点赞 回复
分享
发布于 2020-05-08 00:48

相关推荐

1 12 评论
分享
牛客网
牛客企业服务