前言
2026年5月7号荣耀笔试,共三道题,整体难度一般。
寻找2的次幂
题目描述
给定一个整数 ,输出 ,使得 的 次幂 , 的 次幂 。
输入描述
整数。
输出描述
样例1
输入
5
输出
2
思路和代码
思路: 逻辑分析
- 的 次幂 并且 的 次幂 。让K=N的二进制最高位位置即可。
#include<bits/stdc++.h>
usingnamespacestd;
intmain(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
int k = 0;
while (n != 0) {
n >>= 1;
k++;
}
cout << k - 1;
return0;
}
鸟巢场馆
题目内容
年奥运会举行完成后,鸟巢场馆面临空置的问题。政府希望对外开放鸟巢,允许各公司申请使用。各公司需要提前提交申请,说明使用鸟巢场馆的起始时间与截止时间。公司申请的时间端(包括起始时间与结束时间)独自占用鸟巢,不可以安排其它公司。鸟巢管理方需要合理安排,保证尽可能多的公司都使用到。 在申请截止时间内,收到许多公司的报名。请你设计一个方案,保证尽可能多的公司能够使用到鸟巢。
输入描述
申请公司数 各公司申请的初始时间与结束时间
输出描述
最大可安排公司数量
样例1
输入
4
4 9 9 11 13 19 10 17
输出
2
说明用例各公司起始与结束时间均合法,请不要校验。
思路和代码
思路:贪心
贪心思维:优先让结束时间早的公司活动使用,流出更多时间给后面的公司进行使用。- 对输入的活动时间按照结束时间降序,然后从前往后找出时间不重叠公司活动数量即可。
#include<bits/stdc++.h>
#include<vector>
usingnamespacestd;
intmain(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
if (n == 0) {
cout << 0;
return0;
}
vector<pair<int,int>> times(n);
for (int i = 0; i < n; i++) {
int start,end;
cin >> start >> end;
times[i] = {start, end};
}
// 按照结束时间排序
sort(times.begin(), times.end(), [](pair<int, int> &a, pair<int, int> &b){
return a.second < b.second;
});
int count = 1;
int lastEnd = times[0].second;
for (int i = 1; i < n; i++) {
if (lastEnd < times[i].first) {
lastEnd = times[i].second;
count++;
}
}
cout << count;
return0;
}
鸟巢场馆
题目内容
现在存在 个房间,有 个人需要入住,需要列出所有房间入住可以安排的情况。假设每个房间可以入住的人数限制为 人。限制条件,为了公平起见,不能存在一个房间的人数比别的房间的人数多 个。输出的组合中房间敏感的,即 组合和 组合是不同的组合,都需要输出, 组合代表第一个房间住 个人,第二个房间住 个人,第三个房间住 个人,而 组合代表第一个房间住 个人,第二个房间住 个人,第三个房间住 个人
输入描述
输入房间数和入住人数,中间用逗号分隔
输出描述
第一行输出剩余没有安排人员的数目 第二行输出有几种安排情况 参数异常输出 每一行代表一种情况
样例1
输入
7,11
输出
0
2,2,2,2,1,1,1
2,2,2,1,2,1,1
2,2,2,1,1,2,1
2,2,2,1,1,1,2
2,2,1,2,2,1,1
2,2,1,2,1,2,1
2,2,1,2,1,1,2
2,2,1,1,2,2,1
2,2,1,1,2,1,2
2,2,1,1,1,2,2
2,1,2,2,2,1,1
2,1,2,2,1,2,1
2,1,2,2,1,1,2
2,1,2,1,2,2,1
2,1,2,1,2,1,2
2,1,2,1,1,2,2
2,1,1,2,2,2,1
2,1,1,2,2,1,2
2,1,1,2,1,2,2
2,1,1,1,2,2,2
1,2,2,2,2,1,1
1,2,2,2,1,2,1
1,2,2,2,1,1,2
1,2,2,1,2,2,1
1,2,2,1,2,1,2
1,2,2,1,1,2,2
1,2,1,2,2,2,1
1,2,1,2,2,1,2
1,2,1,2,1,2,2
1,2,1,1,2,2,2
1,1,2,2,2,2,1
1,1,2,2,2,1,2
1,1,2,2,1,2,2
1,1,2,1,2,2,2
1,1,1,2,2,2,2
说明每一行代表一种情况
样例2
输入
3,20
输出
5
5,5,5
样例3
输入
6,11
输出
0
2,2,2,2,2,1
2,2,2,2,1,2
2,2,2,1,2,2
2,2,1,2,2,2
2,1,2,2,2,2
1,2,2,2,2,2
思路和代码
根据题意,可以分类进行处理
- 存在人数无法安排的情况,肯定是
m * 5 <= n, 此时剩余人数数量就是n - m * 5, 此时也只会存在一种安排情况,每个房子全部住满5人。 - 接下来分析
m * 5 > n 说明此时并不是每个房子都能住满,同时题目又限制在一个房间的人数比别的房间的人数多 2 个, 可以推导出每个房子必须住n / m(向下取整)个人,同时剩余n % m可自由安排的人,自由安排的人每个房子只能放置1个,这里求出所有合法情况可以采用递归回溯算法实现。
“至于非法输入,可从数据不完整、不是数字等情况进行考虑。
#include<bits/stdc++.h>
#include<vector>
usingnamespacestd;
int n , m;
int baseNum, extra;
vector<int> rooms;
vector<vector<int>> ans;
booljudgeNumStr(string & str){
for (char c : str) {
if (!isdigit(c)) {
returnfalse;
}
}
returntrue;
}
voiddfs(int start, int cnt){
// 已全部放完
if (cnt == extra) {
ans.push_back(rooms);
return;
}
for (int i = start; i < m; i++) {
rooms[i]++;
dfs(i + 1, cnt + 1);
rooms[i]--;
}
}
intmain(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
string s;
cin >> s;
int pos = s.find(',');
// 输入格式非法
if (pos == string::npos) {
cout << "invalid";
return0;
}
string s1 = s.substr(0, pos);
string s2 = s.substr(pos + 1);
// 空字符串非法 非数字符串也非法
if (s1.empty() || s2.empty() || !judgeNumStr(s1) || !judgeNumStr(s2)) {
cout << "invalid";
return0;
}
m = stoi(s1);
n = stoi(s2);
// 存在剩余情况
if (5 * m <= n) {
// 会存在剩余人数
cout << n - 5 * m << endl;
// 只会存在一种情况
for (int i = 0; i < m; i++) {
if (i != 0) {
cout << ",";
}
cout << "5";
}
return0;
}
baseNum = n / m;
extra = n % m;
// 所有房间先放baseNum
rooms.assign(m, baseNum);
dfs(0, 0);
// 肯定可以全部放置
cout << 0 << endl;
// 输出方案
for (auto &v : ans) {
for (int i = 0; i < m; i++) {
if (i) {
cout << ",";
}
cout << v[i];
}
cout << endl;
}
return0;
}