给下答案
Victor想要成为“完美的先生”。为了实现这个目标,他需要掌握一定的技能。更确切地说,他需要掌握2项技能。Victor有nn本书。阅读第ii本书需要mimi分钟,并会赋予他两种所需技能中的一种(可能没有),用一个长度为2的二进制字符串表示。那么,Victor获得所有两种技能所需的最短时间是多少?
输入
输入包含多个测试用例。第一行包含一个整数t(1≤t≤1000)t(1≤t≤1000) - 测试用例的数量。接下来是测试用例的描述。
每个测试用例的第一行包含一个整数nn(1≤n≤2∗105)(1≤n≤2∗105) - 可用书籍的数量。
然后是n行。第i行包含一个正整数mi(1≤mi≤2∗105)mi(1≤mi≤2∗105),以及长度为2的二进制字符串,其中si1=1si1=1表示读取第ii本书将授予Victor技能1,而si1=0si1=0则表示没有;si2=1si2=1表示读取第i本书将授予Victor技能2,而si2=0si2=0则表示没有。
保证所有测试用例中n的总和不超过2∗1052∗105。
输出
对于每个测试用例,输出一个整数,表示Victor获取所需两种技能所需的最短时间。如果无论读多少本书都无法获得这两种技能,则输出-1。
样例输入
来自chatgpt的回答:
#include <iostream>
#include <queue>
using namespace std;
// 书籍类型
struct Book {
int time; // 读这本书需要的时间
bool skill1; // 是否包含技能1
bool skill2; // 是否包含技能2
};
// 重载小于号运算符,用于 priority_queue 中
bool operator<(const Book& a, const Book& b) {
return a.time > b.time; // 按照读书时间从小到大排序
}
int main() {
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
// 初始化两个队列,分别存储只包含第一种技能和只包含第二种技能的书籍
priority_queue<Book> q1; // 包含技能1且不包含技能2
priority_queue<Book> q2; // 包含技能2且不包含技能1
// 将所有的书籍按照包含技能1和技能2以及获取技能所需时间进行分类,并加入相应的队列中
for (int i = 0; i < n; i++) {
int t;
string s;
cin >> t >> s;
if (s[0] == '1' && s[1] == '0') {
q1.push({t, true, false});
} else if (s[0] == '0' && s[1] == '1') {
q2.push({t, false, true});
} else if (s[0] == '1' && s[1] == '1') {
// 如果同时包含两种技能,则直接忽略掉这本书
} else {
// 不包含任何技能,也直接忽略掉这本书
}
}
// 模拟读书过程
int time = 0; // 已经花费的时间
int cnt = 0; // 已经读完的书籍数
bool hasSkill1 = false; // 是否已经获取了技能1
bool hasSkill2 = false; // 是否已经获取了技能2
while (!q1.empty() || !q2.empty()) { // 只要有一个队列非空就继续读书
if (cnt == n) { // 如果已经读完所有的书籍
if (hasSkill1 && hasSkill2) { // 如果已经获取了全部的技能
cout << time << endl; // 输出花费的时间
} else {
cout << -1 << endl; // 否则输出 -1
}
break;
}
if (hasSkill1 && hasSkill2) { // 如果已经获取了全部的技能,则直接从队列中取出书籍并忽略掉
Book book;
if (!q1.empty() && !q2.empty()) {
// 如果两个队列都非空,则选择读书时间较小的那本书籍
if (q1.top().time < q2.top().time) {
book = q1.top();
q1.pop();
} else {
book = q2.top();
q2.pop();
}
} else if (!q1.empty()) {
book = q1.top();
q1.pop();
} else {
book = q2.top();
q2.pop();
}
time += book.time;
cnt++;
} else if (hasSkill1) { // 如果已经获取了技能1,则从第二个队列中取出时间最短的书籍
if (q2.empty()) {
cout << -1 << endl;
break;
}
Book book = q2.top();
q2.pop();
time += book.time;
cnt++;
if (book.skill1) {
q1.push(book);
} else {
hasSkill2 = true;
}
} else if (hasSkill2) { // 如果已经获取了技能2,则从第一个队列中取出时间最短的书籍
if (q1.empty()) {
cout << -1 << endl;
break;
}
Book book = q1.top();
q1.pop();
time += book.time;
cnt++;
if (book.skill2) {
q2.push(book);
} else {
hasSkill1 = true;
}
} else { // 如果还没有获取全部的技能,则从两个队列中选择花费时间最少的那本书籍开始读
if (q1.empty() || q2.empty()) {
cout << -1 << endl;
break;
}
Book book1 = q1.top();
Book book2 = q2.top();
if (book1.time < book2.time) {
q1.pop();
time += book1.time;
cnt++;
if (book1.skill2) {
q2.push(book1);
} else {
hasSkill1 = true;
}
} else {
q2.pop();
time += book2.time;
cnt++;
if (book2.skill1) {
q1.push(book2);
} else {
hasSkill2 = true;
}
}
}
}
}
return 0;
}