本次竞赛题目比较简单,主要还是看对题意的理解和手速了。
第一题
题目描述
题目名称:求并集
由小到大输出两个单向有序链表的并集 如链表 A {1 -> 2 -> 5 -> 7} 链表 B {3 -> 5 -> 7 -> 8} 输出: {1 -> 2 ->3 -> 5 -> 7 ->8} 。
题解
高频面试题,题目本意是合并两个有序链表并且相同元素只保留一次,面试当然要用链表写,但比赛明显直接排序输出更为方便,下面是AC代码。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
vector<int> num(n + m);
for (int i = 0; i < n + m; i++) {
cin >> num[i];
}
sort(num.begin(), num.end());
for (int i = 0; i < num.size(); i++) {
if (i && num[i] == num[i - 1]) continue;
if (i) {
cout << " -> ";
}
cout << num[i];
}
cout << endl;
return 0;
}
复杂度分析
时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn),其中n为两个链表的长度之和。
第二题
题目描述
题目名称:小T找糖豆
已知连续序列A,包含1e18个元素,分别是[1,1e8]。 现在去除序列中的n个元素. 得到新的连续序列[X,1e8],该序列中最小元素是?
题解
根据题意,显然我们只需要找到去除的n个元素中的最大值,而题目所求的X就是前面得到的最大值+1,下面是AC代码。
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n;
cin >> n;
int flag = 0;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
flag = max(flag, x);
}
cout << flag + 1 << endl;
return 0;
}
复杂度分析
时间复杂度为 O ( n ) O(n) O(n),n为删除的元素个数。
第三题
题目描述
题目名称:争风吃醋的豚鼠
N个节点两两建边。 不存在3个节点相互之前全部相连(3个节点连接成环) 。最多能建立多少条边?
题解
我们可以证明,只要将这N个节点分为两个集合,并且不允许集合内部节点相连,只允许位于不同集合的节点相连,就一定不存在三元环。至此,这明显是一个数学问题(类似,已知长方形长宽之和,求它面积的最大值),下面是AC代码。
#include <iostream>
#include <math.h>
using namespace std;
int main() {
int n;
cin >> n;
if (n == 1) cout << 0 << endl;
else if (n == 2) cout << 1 << endl;
else {
if (n%2) {
cout << (n-1)/2*(n+1)/2 << endl;
} else {
cout << n/2*n/2 << endl;
}
}
return 0;
}
复杂度分析
很明显,这是一个 O ( 1 ) O(1) O(1)时间复杂度的问题。
第四题
题目描述
题目名称:选择客栈
丽江河边有 n 家很有特色的客栈,客栈按照其位置顺序从 1 到 n 编号。每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均有各自的最低消费。 两位游客一起去丽江旅游,他们喜欢相同的色调,又想尝试两个不同的客栈,因此决定分别住在色调相同的两家客栈中。晚上,他们打算选择一家咖啡店喝咖啡,要求咖啡店位于两人住的两家客栈之间(包括他们住的客栈),且咖啡店的最低消费不超过 p 。 他们想知道总共有多少种选择住宿的方案,保证晚上可以找到一家最低消费不超过 p 元的咖啡店小聚。
题解
根据题意,我们需要统计两家酒店色调相同且中间存在咖啡店最低消费小于预期值的组合数。那么我们可以在输入时就直接对酒店颜色出现次数,该颜色酒店最后出现位置进行统计,同时判断当前咖啡店最低消费是否小于预期值,如果小于就在最终结果上添加该色调酒店之前出现次数。下面是贪心法AC代码。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 200005;
int main() {
int n, k, p;
cin >> n >> k >> p;
int color, pth, now, ans;
int last[N], sum[N], cnt[N];
for (int i = 1; i <= n; i++) {
cin >> color >> pth;
if (pth <= p)
now = i;
if (now >= last[color])
sum[color] = cnt[color];
last[color] = i;
ans += sum[color];
cnt[color]++;
}
cout << ans << endl;
return 0;
}
复杂度分析
时间复杂度为 O ( n ) O(n) O(n),其中n为客栈数量。