牛客网真题练习-01
Posted zhang--yd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客网真题练习-01相关的知识,希望对你有一定的参考价值。
牛客网真题练习-01
双核处理
一种双核CPU的两个核能够同时的处理任务,现在有n个已知数据量的任务需要交给CPU处理,假设已知CPU的每个核1秒可以处理1kb,每个核同时只能处理一项任务。n个任务可以按照任意顺序放入CPU进行处理,现在需要设计一个方案让CPU处理完这批任务所需的时间最少,求这个最小的时间。
输入描述:
输入包括两行: 第一行为整数n(1 ≤ n ≤ 50) 第二行为n个整数length[i](1024 ≤ length[i] ≤ 4194304),表示每个任务的长度为length[i]kb,每个数均为1024的倍数。
输出描述:
输出一个整数,表示最少需要处理的时间
输入例子
5 3072 3072 7168 3072 1024
输出例子:
9216
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; const int MAXN = 55; const int MAXM = 800000; int n,sum, num[MAXN], dp[MAXM]; int main(){ freopen("in.txt", "r", stdin); int tmp, ans; scanf("%d", &n); sum = 0; for(int i=0; i<n; ++i){ scanf("%d", &num[i]); sum += num[i]; } memset(dp, 0, sizeof(dp)); dp[0] = 1; for(int i=0; i<n; ++i){ tmp = num[i]/1024; for(int j=sum/1024; j>=tmp; --j){ if(dp[j - tmp] == 1){ dp[j] = 1; } } } ans = 0; tmp = sum/(2*1024); for(int i=0; i<sum/1024; ++i){ if(dp[tmp-i] == 1){ ans = 1024*(tmp-i); break; } if(dp[tmp+i] == 1){ ans = 1024*(tmp+i); break; } } ans = max(sum-ans, ans); printf("%d\n", ans ); return 0; }
赶去公司
终于到周末啦!小易走在市区的街道上准备找朋友聚会,突然服务器发来警报,小易需要立即回公司修复这个紧急bug。假设市区是一个无限大的区域,每条街道假设坐标是(X,Y),小易当前在(0,0)街道,办公室在(gx,gy)街道上。小易周围有多个出租车打车点,小易赶去办公室有两种选择,一种就是走路去公司,另外一种就是走到一个出租车打车点,然后从打车点的位置坐出租车去公司。每次移动到相邻的街道(横向或者纵向)走路将会花费walkTime时间,打车将花费taxiTime时间。小易需要尽快赶到公司去,现在小易想知道他最快需要花费多少时间去公司。
输入描述:
输入数据包括五行:
第一行为周围出租车打车点的个数n(1 ≤ n ≤ 50)
第二行为每个出租车打车点的横坐标tX[i] (-10000 ≤ tX[i] ≤ 10000)
第三行为每个出租车打车点的纵坐标tY[i] (-10000 ≤ tY[i] ≤ 10000)
第四行为办公室坐标gx,gy(-10000 ≤ gx,gy ≤ 10000),以空格分隔
第五行为走路时间walkTime(1 ≤ walkTime ≤ 1000)和taxiTime(1 ≤ taxiTime ≤ 1000),以空格分隔
输出描述:
输出一个整数表示,小易最快能赶到办公室的时间
输入例子:
2 -2 -2 0 -2 -4 -2 15 3
输出例子:
42
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> using namespace std; const int MAXN = 50; int X[MAXN], Y[MAXN]; int main(){ freopen("in.txt", "r", stdin); int ans, gx, gy, Wt, Tt, n, tmp; scanf("%d", &n); for(int i=0; i<n; ++i){ scanf("%d", &X[i]); } for(int i=0; i<n; ++i){ scanf("%d", &Y[i]); } scanf("%d%d", &gx, &gy); scanf("%d%d", &Wt, &Tt); ans = (abs(gx) + abs(gy))*Wt; for(int i=0; i<n; ++i){ tmp = (abs(X[i]) + abs(Y[i]))*Wt + (abs(gx - X[i]) + abs(gy - Y[i]))*Tt; if(tmp < ans){ ans = tmp; } } printf("%d\n", ans ); return 0; }
消除重复元素
小易有一个长度为n序列,小易想移除掉里面的重复元素,但是小易想是对于每种元素保留最后出现的那个。小易遇到了困难,希望你来帮助他。
输入描述:
输入包括两行: 第一行为序列长度n(1 ≤ n ≤ 50) 第二行为n个数sequence[i](1 ≤ sequence[i] ≤ 1000),以空格分隔
输出描述:
输出消除重复元素之后的序列,以空格分隔,行末无空格
输入例子:
9 100 100 100 99 99 99 100 100 100
输出例子:
99 100
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <map> #include <vector> using namespace std; const int MAXN = 55; int main(){ freopen("in.txt", "r", stdin); int n, num[MAXN]; scanf("%d", &n); for(int i=0; i<n; ++i){ scanf("%d", &num[i]); } vector<int> ans; map<int, int> mp; for(int i=n-1; i>=0; --i){ if( mp.find( num[i] ) == mp.end()){ mp[ num[i] ] = 1; ans.push_back( num[i] ); } } for(int i=ans.size()-1;i>=0; --i){ if(i==0){ printf("%d\n", ans[i] ); }else{ printf("%d ", ans[i] ); } } return 0; }
工作安排
现在有n位工程师和6项工作(编号为0至5),现在给出每个人能够胜任的工作序号表(用一个字符串表示,比如:045,表示某位工程师能够胜任0号,4号,5号工作)。现在需要进行工作安排,每位工程师只能被安排到自己能够胜任的工作当中去,两位工程师不能安排到同一项工作当中去。如果两种工作安排中有一个人被安排在的工作序号不一样就被视为不同的工作安排,现在需要计算出有多少种不同工作安排计划。
输入描述:
输入数据有n+1行: 第一行为工程师人数n(1 ≤ n ≤ 6) 接下来的n行,每行一个字符串表示第i(1 ≤ i ≤ n)个人能够胜任的工作(字符串不一定等长的)
输出描述:
输出一个整数,表示有多少种不同的工作安排方案
输入例子:
6 012345 012345 012345 012345 012345 012345
输出例子:
720
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> using namespace std; const int MAXN = 10; int n, ans, var[MAXN][MAXN], vis[MAXN]; void dfs(int cur){ if(cur == n){ ans++; return; } for(int i=0; i<=5; ++i){ if(vis[i] == 0 && var[cur][i] == 1){ vis[i] = 1; dfs(cur+1); vis[i] = 0; } } } int main(){ freopen("in.txt", "r", stdin); char st[MAXN]; scanf("%d", &n); memset(var, 0, sizeof(var)); for(int i=0; i<n; ++i){ scanf("%s", st); for(int j=0; j<strlen(st); ++j){ var[i][st[j]-‘0‘] = 1; } } ans = 0; memset(vis, 0, sizeof(vis)); dfs(0); printf("%d\n", ans ); return 0; }
奇怪的表达式求值
常规的表达式求值,我们都会根据计算的优先级来计算。比如*/的优先级就高于+-。但是小易所生活的世界的表达式规则很简单,从左往右依次计算即可,而且小易所在的世界没有除法,意味着表达式中没有/,只有(+, - 和 *)。现在给出一个表达式,需要你帮忙计算出小易所在的世界这个表达式的值为多少
输入描述:
输入为一行字符串,即一个表达式。其中运算符只有-,+,*。参与计算的数字只有0~9. 保证表达式都是合法的,排列规则如样例所示。
输出描述
输出一个数,即表达式的值
输入例子:
3+5*7
输出例子:
56
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; const int MAXN = 100; int main(){ char st[MAXN]; int flag, ans, tmp, len, i; while(scanf("%s", st) != EOF){ ans = 0; len = strlen(st); tmp = 0; i = 0; flag = 1; while(i < len){ if(st[i] == ‘+‘){ flag = 1; }else if(st[i] == ‘-‘){ flag = 2; }else if(st[i] == ‘*‘){ flag = 3; }else{ tmp = st[i] - ‘0‘; while(i < len && st[i+1]>=‘0‘ && st[i+1]<=‘9‘){ i++; tmp = tmp*10 + st[i]-‘0‘; } if(flag==1){ ans += tmp; }else if(flag==2){ ans -= tmp; }else{ ans *= tmp; } } i++; } printf("%d", ans); } return 0; }
涂棋盘
小易有一块n*n的棋盘,棋盘的每一个格子都为黑色或者白色,小易现在要用他喜欢的红色去涂画棋盘。小易会找出棋盘中某一列中拥有相同颜色的最大的区域去涂画,帮助小易算算他会涂画多少个棋格。
输入描述:
输入数据包括n+1行:
第一行为一个整数n(1 ≤ n ≤ 50),即棋盘的大小
接下来的n行每行一个字符串表示第i行棋盘的颜色,‘W‘表示白色,‘B‘表示黑色
输出描述:
输出小易会涂画的区域大小
输入例子:
3 BWW BBB BWB
输出例子:
3
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> using namespace std; const int MAXN = 55; int n, ans, tmp, mp[MAXN][MAXN]; void dfs(int cx, int cy, int label){ tmp++; mp[cx][cy] = 0; if(cx+1<n && mp[cx+1][cy] == label){ dfs(cx+1, cy, label); } } int main(){ char ch; scanf("%d", &n); for(int i=0; i<n; ++i){ getchar(); for(int j=0; j<n; ++j){ scanf("%c", &ch); if(ch == ‘B‘){ mp[i][j] = -1; }else{ mp[i][j] = 1; } } } ans = 0; for(int i=0; i<n; ++i){ for(int j=0; j<n; ++j){ if(mp[i][j] != 0){ tmp = 0; dfs(i, j, mp[i][j]); if(tmp > ans){ ans = tmp; } } } } printf("%d", ans); return 0; }
以上是关于牛客网真题练习-01的主要内容,如果未能解决你的问题,请参考以下文章