题目一
I-礼物商店_第二届“重科杯”重庆科技大学程序设计竞赛 (nowcoder.com)
题解
感想:这道题目没有太多技术含量,只需要用一个优先队列每一次维护一个结构体,结构体的成员分别是价格和数量。但是对于初学者的我,有很多可以注意的地方。
结构体含有带参数的构造函数
这道题目我首先在结构体内定义了带有参数的构造函数。现在,应该注意的地方来了:
如果我在结构体内定义了带有参数的构造函数,那么我将不能声明一个结构体的数组。
报错代码
struct Goods {
int w;
int cnt;
// 带参数的构造函数
Goods(int a, int b) : w(a), cnt(b) {}
};
Goods items[10]; // 编译错误:没有默认构造函数
如果我们试图声明这种结构体或类的数组而没有提供默认构造函数,编译器会因为没有合适的构造函数来初始化数组中的每个元素而报错。
那么我们应该怎么解决呢?
那我们就可以在结构体同时定义参数构造函数还有默认构造函数
struct Goods {
int w;
int cnt;
// 默认构造函数
Goods() : w(0), cnt(0) {}
// 带参数的构造函数
Goods(int a, int b) : w(a), cnt(b) {}
};
Goods items[10]; // 现在这是有效的,每个元素都会使用默认构造函数初始化
结构体不含有带参数的构造函数
如果结构不含带参数的构造函数,那么就简单一点了,结构体代码如下
其中 ll 是 long long
struct Goods{
ll w; // 商品价格
ll cnt; // 可购买次数
}a[N];
完整AC代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5+10;
struct Goods{
ll w; // 商品价格
ll cnt; // 可购买次数
}a[N];
struct Compare{
bool operator()(Goods a, Goods b){
return a.w > b.w; // 优先队列,最小的价格在顶部
}
};
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n, m, k;
cin >> n >> m >> k;
priority_queue<Goods, vector<Goods>, Compare> pq;
for(int i = 0; i < m; i++) cin >> a[i].cnt;
for(int i = 0; i < m; i++) {
cin >> a[i].w;
pq.push({a[i].w, a[i].cnt}); // 正确推入价格 w 和数量 cnt,这里的顺序不能换哦
}
ll ans = 0;
while(n--) {
if (pq.empty()) break; // 避免队列为空时继续访问
Goods temp = pq.top(); pq.pop();
ans += temp.w; // 累加价格
temp.cnt--; // 减少剩余可购买次数
if(temp.cnt > 0) {
temp.w = (temp.w + k) | (temp.w & k); // 更新价格
pq.push(temp); // 如果还可以购买,重新入队
}
}
cout << ans << '\n';
return 0;
}
那么我们可以在某些情况下省略带参数的构造函数,什么时候需要呢?
当我们的结构体对象包含多个成员变量,且这些变量在创建对象时需要立即被初始化为特定值时,带参数的构造函数非常有用。这样可以确保对象在使用前已正确设置其状态。例如,在处理几何问题时,定义点、向量或其他几何结构体并立即赋予坐标值。

被折叠的 条评论
为什么被折叠?



