华为机试4月17
第一第二道过了百分之百,第三道百分之95。
第三道可能是我没有用状态压缩,提前交卷了。
第一题排序
输入 h , m
h表示小明的身高
m 表示下一行有 m 个人的身高
要求输出与小明身高差最小的,按照从小到大排序。
思路:
用哈希表记录当前身高差和与小明身高差的绝对值,然后按照从小到大排序,身高差相同则按照先后顺序
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
int main(){
int h,n;
cin >> h >> n;
vector<int> nums(n);
vector<pair<int,int> > res;
for(int i = 0; i < n; i++){
cin >> nums[i];
res.push_back(make_pair(nums[i], abs(h - nums[i])));
}
sort(res.begin(), res.end(), [](const pair<int,int>& a, const pair<int,int>& b){
if(a.second == b.second) return a.first < b.first;
return a.second < b.second;
});
for(int i = 0; i < n; i++){
if(i == n - 1){
cout << res[i].first << endl;
}
else cout << res[i].first << " ";
}
return 0;
} 第二题,判断是不是在一个队
输入 n ,m
n 表示从 1-n,
m表示后面有 m 行
a b c
a,b要在(1,n)内
c = 0 表示在一个队内,输出we are a team,
c = 1 表示需要判断
c = 其他则输出da pian zi
如果不在一个队就输出we are not a team
思路:
标准的并查集
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
const int N = 1e5 + 10;
int n,m;
vector<int> fa;
void init(int len){
fa.resize(len);
for(int i = 0; i < len; i++){
fa[i] = i;
}
}
int find(int x){
if(x != fa[x]){
fa[x] = find(fa[x]);
}
return fa[x];
}
void merge(int x, int y){
x = find(x);
y = find(y);
fa[x] = y;
}
int main(){
cin >> n >> m;
if(n < 1 || n > 100000 || m < 1 || m > 100000){
cout << "NULL\n";
return 0;
}
init(n);
for(int i = 0; i < m; i++){
int x, y, p;
cin >> x >> y >> p;
if(x < 1 || x > n || y < 1 || y > n){
cout << "da pian zi\n";
}else{
if(p == 0){
merge(x, y);
}
else if(p == 1){
if(find(x) == find(y)){
cout << "we are a team\n";
}else{
cout << "we are not a team\n";
}
}else{
cout << "da pian zi\n";
}
}
}
return 0;
}
第三题: 组成一面墙的最小层数
墙只能由高和宽相对堆叠。
输入:给定一组数据,用空格分开(应该是宽度,记不清了)
例如:
3 6 3 3 3
输出 3,
解释:以 6 为底的墙,第一层为 6 ,第二层为 3 + 3 第三层 3 + 3
思路:
一开始看到有点懵,后面一想不就是背包问题吗,先计算和sum,排序,我们选取最大的maxVal作为墙的第一层
如果 sum % maxVal == 0,代表可以这样划分,如果不可以则 maxVal += maxVal + nuns[i], 加上最小的。
可以化分的层数就为 cnt = sum / maxVal
背包容量就为:sum /= cnt;
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
void Stringsplit(string str, const char split, vector<int>& res){
istringstream iss(str);
string tmp;
while(getline(iss, tmp, split)){
res.push_back(stoi(tmp));
}
}
int main(){
string str;
vector<int> nums;
getline(cin,str);
Stringsplit(str, ' ', nums);
int n = nums.size();
if(n == 1){
cout << 1 << endl;
return 0;
}
if(n == 0){
cout << -1 << endl;
return 0;
}
sort(nums.begin(), nums.end());
int maxVal = nums[n - 1];
int sum = 0;
for(int i = 0; i < n; i++){
sum += nums[i];
}
for(int i = 0; i < n - 1; i++){
if(sum % maxVal == 0){
break;
}else{
maxVal += nums[i];
}
}
int cnt = sum / maxVal;
sum /= cnt;
vector<vector<bool> > dp(n + 1, vector<bool>(sum + 1, false));
//base case
for(int i = 0; i <= n; i++){
dp[i][0] = true;
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= sum; j++){
if(j - nums[i - 1] < 0){
dp[i][j] = dp[i - 1][j];
}else{
dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i - 1]];
}
}
}
if(dp[n][sum] == true){
cout << cnt << endl;
}else{
cout << -1 << endl;
}
return 0;
}
查看10道真题和解析