【CODE】2020技术岗笔试

55 篇文章 0 订阅

1.扎银花

两组数据比大小,取出最大的三个数比较他们的和,输出和更大的那个数,如果一样,也输出。

  • 使用内置的sort比手写bubblesort只取前三个更快?

2.最长上升子串构造

从序列中删除一个数,求所有的删除方案中,最长上升子串(连续的)的长度。

#include"pch.h"
#include <iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
int main() {
	int n;
	cin >> n;
	vector<int> num(n);
	vector<int> len(n);//以当前节点为首,最长连续递增子序列长度
	vector<int> start(n);//当前节点为尾,最长连续递增子序列的首位置
	len[n - 1] = 1;
	start[0] = 0;
	int maxx = 0;
	for (int i = 1; i < n; i++) {
		if (num[i] < num[i - 1]) start[i] = start[i - 1];
		else start[i] = i;
	}
	for (int i = n - 2; i >= 0; i--) {
		if (num[i] < num[i + 1]) {
			len[i] = len[i - 1] + 1;
			maxx = max(len[i], maxx);
		}
		else len[i] = 1;
	}
	int res = 0;
	for (int i = 1; i < n; i++) {
		if (num[i - 1] < num[i + 1]) {
			int tmp = len[i + 1] + start[i-1] - i;
			maxx = max(tmp, maxx);
		}
	}
	cout << maxx;
	return 0;
}

3.做任务

n个任务,对于每个任务都有k个子任务,每个子任务花费的时间与父任务无关,只与出现顺序有关,每个父任务、子任务都只能完成一次,完成一个子任务会给p分,完成一个任务的k个子任务后,会得到额外的q分,求m时间内,最大得分。

#include"pch.h"
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
/*3.n个任务,对于每个任务都有k个子任务,
每个子任务花费的时间与父任务无关,
只与出现顺序有关,每个父任务、子任务都只能完成一次,
完成一个子任务会给p分,完成一个任务的k个子任务后,
会得到额外的q分,求m时间内,最大得分*/
int main() {
	int n, k, m, p, q;
	cin >> n >> k >> m >> p >> q;
	vector<int> jobs(k);//k个子任务
	long res = 0;
	long sum = 0;//单个任务总时长
	for (int i = 0; i < k; i++) {
		cin >> jobs[i];
		sum += jobs[i];//统计一个父任务的总时长
	}
	sort(jobs.begin(), jobs.end());
	int l = (int)(m / sum);//最多能完成几个父任务
	if (n < l) l = n;
	for (int i = 0; i <= l; i++) {
		long time = m - sum * i;//完成i个父任务后还剩多少时间
		long score = i * (p*k + q);//完成i个父任务的总分
		int remain = n - i;//剩下多少个父任务没有完成
		for (int j = 0; j < k; j++) {//尝试完成子任务
			if (jobs[j] * remain > time) {
				//剩余时间t < 完成剩余父任务的第j个子任务
				score += ((time / jobs[j])*p);
				//得得分数+剩余时间能够完成的第j个子任务的个数
				break;
			}
			else {
				time -= jobs[j] * remain;
				//剩余时间够的话,就减去完成剩余父任务所有j子任务的时间
				score += p * remain;
			}
		}
		if (score > res) res = score;
	}
	cout << res;
	return 0;
}

4. 跑步

准备正好跑k距离,城市道路可以看成n个点,m条无向边组成的无向图,每边由固定的长度。

跑步前往一个目的地时一定要走最短距离,如果正好跑k距离,能够到达的目的地的个数,目的地可能在图的点上,也可能在边上,且该目的地距离他起点的最短路径正好k距离。

若k大于所有路径之和,自然没有这样的目的地,返回0。

示例:点数,边数,起点编号,m行无向边:u->v,w长度,下一行:k

3 3 1

1 2 2

2 3 3

1 3 4

4

输出:2,目的地是编号3的点,以及在2->3路径2/3处的一个点。

#include"pch.h"
#include <iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
const int maxn = 1000;
const int INF = 1000000;
int n, m, k;
int d[maxn], w[maxn][maxn],g[maxn][maxn];
int vis[maxn] = { 0 };
void dijkstra(int s) {
	fill(d, d + maxn, INF);
	d[s] = 0;
	int i, j, v;
	for (i = 0; i < n; i++) {
		int u = -1;
		int min = INF;
		for (j = 0; j < n; j++) {
			if (vis[j] == 0 && d[j] < min) {
				u = j; min = d[j];
			}
		}
		if (u == -1) return;
		vis[u] = 1;
		for (v = 0; v < n;v++) {
			if (vis[v] == 0 && g[u][v]!=INF) {
				if (d[v] > d[u] + g[u][v]) {
					d[v] = d[u] + g[u][v];
				}
			}
		}
	}
}
int main() {
	int s;
	cin >> n >> m >> s;
	fill(g[0], g[0] + maxn * maxn, INF);
	for (int i = 0; i < n; i++) {
		int a, b, c;
		cin >> a >> b >> c;
		g[a-1][b-1] = c;
		g[b-1][a-1] = c;

	}
	cin >> k;
	dijkstra(s-1);
	int res = 0;
	for (int i = 0; i < n; i++) {
		if (d[i] == k) res++;//cout << d[i] << " ";
	}//s到每个点的最短距离
	//再求,到各个边上点的情况
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			if (g[i][j] == INF) continue;
			if (d[i]<k && d[i] + g[i][j]>k) {
				int tmp = d[i] + g[i][j] - k;
				if (d[j] + tmp >= k) res++;
			}
		}
	}
	cout << res;
	return 0;
}
  • 不知道对不对
  • 利用dijkstra,先求起点到其余各点的最短距离
  • 再求在边上的情况,u-v这条边,dis[u]<k && dis[u]+g[u][v]>k,且从u到达比从v到达这个点要近,就是说这个边上的这个点,最短距离是从u来的,也算是一种情况

5.序列最长不下降子序列

1,0,0,1,1的最长不下降子序列是0,0,1,1

某序列只有1和0,完成(1)某段区间的0变成1,(2)求整段序列的最长不下降子序列长度,每组操作后都会对序列造成改变,就是说整个序列会不停变化。

输入:n,m,序列长度和查询次数 (n:[1,100000],m:[1,100000],x,y:[1,n])

           n行无空格的数字,只有0或1

           m行个询问,两个操作的询问方式:(1)c x y 将区间[x,y]的0变为1,1变为0(2)q 询问整段序列的最长不下降子序列长度。(整个序列下标:1,2,3,...,n)

输出:对于q类询问,输出最长不下降自序列长度

示例:

5 5

10011    

q           长度:4

c 1 5     修改后变成:01100

q           长度:3

c 1 3     修改后变成:10000

q           长度:4

输出:4 3 4

    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值