首页 > 腾讯3.21笔试题解(AK)
头像
sysugjh
编辑于 2021-04-07 10:03
+ 关注

腾讯3.21笔试题解(AK)

1. DFS搜索节点路径
代码没在本地打,每个val跑一遍前序,回溯生成链表就好

2. 记忆化搜索
#include <stdio.h>
#include <limits.h>
#include <unordered_map>
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;

unordered_map<int, int> m;

int ans(int n){
	if(n <= 2) return n;
	if(m.count(n)) return m[n];
	m[n] = min(ans(n/2)+n%2, ans(n/3)+n%3)+1;
	return m[n];
}

int main(){
	int t, n;
	scanf("%d", &t);
	while(t--){
		scanf("%d", &n);
		printf("%d\n", ans(n));
	}
	return 0;
}
3. 模拟多个有序数组merge过程即可
#include <bits/stdc++.h>
using namespace std;

int b[100010];
typedef pair<int,int> T;
int ans(vector<vector<int> > &a, int p, int k){
	priority_queue<T, vector<T>, greater<T> > q;
	vector<int> index(p, 1);
	for(int i = 0; i < p; i++){
		q.push(make_pair(a[b[i]][0], i));
	}
	int cnt = 1;
	while(cnt < k){
		int i = q.top().second;
		q.pop();
		if(index[i] < a[b[i]].size()) {
			q.push(make_pair(a[b[i]][index[i]], i));
			index[i]++;
		}
		cnt++;
	}
	return q.top().first;
}

int main(){
	int n, m, q, p, k;
	scanf("%d", &n);
	vector<vector<int> > a(n+1);
	for(int i = 1; i <= n; ++i){
		scanf("%d", &m);
		a[i].resize(m);
		for(int j = 0; j < m; ++j)
			scanf("%d", &a[i][j]);
		sort(a[i].begin(), a[i].end());
	}
	scanf("%d", &q);
	while(q--){
		scanf("%d", &p);
		for(int i = 0; i < p; ++i){
			scanf("%d", &b[i]);
		}
		scanf("%d", &k);
		printf("%d\n", ans(a, p, k));
	}
	return 0;
}
4. 二分
#include <stdio.h>
#include <algorithm>
using namespace std;
#define max(a,b) ((a)>(b)?(a):(b))
struct node{
    int x, y;
};

bool cmp(const node &a, const node &b){
    return a.x < b.x;
}

node a[100010];
int check(long long w, int n, int x){
    long long sum = 0;
    int cntl = 0, cntr = 0;
    for(int i = 0; i < n; ++i){
        if(a[i].y < x) {
            sum += a[i].x;
            cntl++;
        }
        else if(a[i].x > x) {
            sum += a[i].x;
            cntr++;
        }
    }
    int t = n / 2;
    if(cntl > t) return 1;//too high
    if(cntr > t) return -1; //too low
    for(int i = 0; i < n && cntl < t; i++){
        if(a[i].x <= x && x <= a[i].y){
            sum += a[i].x;
            cntl++;
        }
    }
    if(sum + (t-cntr)*x + x <= w) return 0;
    return 1; //too high
}

int main(){
    int n;
    long long w;
    scanf("%d%lld", &n, &w);
    for(int i = 0; i < n; ++i) scanf("%d%d", &a[i].x, &a[i].y);
    sort(a, a+n, cmp);
    long long sum = 0;
    int l = 0, r = 1e9, ans = 0;
    while(l <= r){
        int mid = (l+r)/2, res = check(w, n, mid);
        if(res == 0){
            ans = mid;
            l = mid+1;
        }
        else if(res == 1) r = mid-1;
        else l = mid+1;
    }
    printf("%d\n", ans);
    return 0;
}

5. 类似背包问题,求模dp,w数组可去掉
#include <stdio.h>
#include <string.h>
#define N 100010
#define min(a,b) ((a)<(b)?(a):(b))
int w[N];
long long dp[101];
bool v[101];
int main(){
	int t, n, m;
	scanf("%d", &t);
	while(t--){
		scanf("%d%d", &n, &m);
		memset(dp, -1, sizeof(dp));
		long long sum = 0;
		dp[0] = 0;
		for(int i = 0; i < n; ++i) {
			scanf("%d", &w[i]);
			long long dp2[101]; //可以用滚动数组 
			for(int i = 0; i < m; ++i) dp2[i] = dp[i];
			for(int j = 0; j < m; ++j){
				if(dp[j] == -1) continue;
				if(dp2[(j+w[i])%m] == -1 || dp2[(j+w[i])%m] < dp[j] + w[i]) {
					dp2[(j+w[i])%m] = dp[j] + w[i];
				}
			}
			for(int i = 0; i < m; ++i) dp[i] = dp2[i];
			sum += w[i];
		}
		printf("%lld\n", sum-dp[0]);
	}
	return 0;
}


全部评论

(3) 回帖
加载中...
话题 回帖

推荐话题

相关热帖

近期热帖

近期精华帖

热门推荐