AcWing第62场周赛
分析:可以用map来存储每个数和每个数对应的下标,因为map本身就是一个有序数组,我们只需在最后输出前三个数的下标即可。
代码:
#include <iostream>
#include <map>
#include <vector>
using namespace std;
int main()
{
int n;
cin >> n;
map<int, int> pos;//用map存储每个数int以及每个数对应的下标int
for (int i = 1; i <= n; i ++ )
{
int x;
cin >> x;
pos[x] = i;//x的下标为i
}
if (pos.size() < 3) puts("-1 -1 -1");
else
{
vector<int> res;
for (auto [x, p]: pos) res.push_back(p);
for (int i = 0; i < 3; i ++ )
cout << res[i] << ' ';
cout << endl;
}
return 0;
}
分析:该题属于数据结构模拟问题,需要找到一个方法能快速判断集合中是否每种卡牌都存在。用变量tot维护当前状态下一共有多少个不同的数
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010;
int n, m;
int cnt[N];//存储不同种类每张卡牌数量
int main()
{
scanf("%d%d", &n, &m);
int tot = 0;//目前拥有的卡牌种类数量
while (m -- )
{
int x;
scanf("%d", &x);
if (!cnt[x]) tot ++ ;
cnt[x] ++ ;
if (tot == n)
{
printf("1");
for (int i = 1; i <= n; i ++ )
if ( -- cnt[i] == 0)//如果卡片i的数量为0了,tot就减一
tot -- ;
}
else
{
printf("0");
}
}
return 0;
}
Leetcode第304场周赛
分析:有点类似于AC第60场周赛的第二题。同样先对数组进行排序,找到每次满足条件的x,每次操作都是要减去最小的非零元素,第一个最小非0元素一次操作之后就变成了0,下一次操作要输出的就是第二个元素a[1]=a[1]-a[0],直到最后一个元素也为0即可。
代码:
class Solution {
public:
int minimumOperations(vector<int>& nums) {
//每次减去x之后,重新排序,若最后一个元素为0即结束
int res = 0;
int n = nums.size();
int x = 110;
sort(nums.begin(),nums.end());
while(nums[n - 1] != 0){
//找每一次的x
for(int i = 0;i < n;i ++){
if(nums[i] > 0 && nums[i] < x){
x = nums[i];
}
}
//每个元素减去x
for(int i = 0;i < n;i ++){
if(nums[i] > 0){
nums[i] -= x;
}
}
//对元素进行重新排序
sort(nums.begin(),nums.end());
res ++;
//重新记录x
x = 110;
}
return res;
}
};
第二题:6133. 分组的最大数量
分析:先将学生成绩排序,然后第1个学生一组,第2和第3个学生一组,第4,5,6个学生一组,依此类推,第到第
个学生一组,当最后剩余元素数量小于或者等于已经分好的最后一组时,把所有剩余的元素添到该组。这样既能保证每组的总分是递增的,又能保证每组的人数是递增的。思路参考
代码:
class Solution {
public:
int maximumGroups(vector<int>& grades) {
int n = grades.size();
int i = 1;
int ans = 0;
while(n >= i){
ans ++;
n -= i;
i ++;
}
return ans;
}
};