C. Mr. Perfectly Fine
题目描述
Timur has n candies. The i-th candy has a quantity of sugar equal to ai. So, by eating the i-th candy, Timur consumes a quantity of sugar equal to ai.
Timur will ask you q queries regarding his candies. For the j-th query you have to answer what is the minimum number of candies he needs to eat in order to reach a quantity of sugar greater than or equal to xj or print -1 if it's not possible to obtain such a quantity. In other words, you should print the minimum possible k such that after eating k candies, Timur consumes a quantity of sugar of at least xj or say that no possible k exists. Note that he can't eat the same candy twice and queries are independent of each other (Timur can use the same candy in different queries).
输入描述:
The first line of input contains a single integer t (1≤t≤1000) — the number of test cases. The description of test cases follows.
The first line contains 2 integers n and q (1≤n,q≤1.5⋅10^5) — the number of candies Timur has and the number of queries you have to print an answer for respectively. The second line contains n integers a1,a2,…,an (1≤ai≤104) — the quantity of sugar in each of the candies respectively. Then q lines follow. Each of the next q lines contains a single integer xj (1≤xj≤2⋅10^9) – the quantity Timur wants to reach for the given query. It is guaranteed that the sum of n and the sum of q over all test cases do not exceed 1.5⋅105.
输出描述:
Output For each test case output q lines. For the j-th line output the number of candies Timur needs to eat in order to reach a quantity of sugar greater than or equal to xj or print -1 if it's not possible to obtain such a quantity.
输入
6
4
2 00
3 10
4 01
4 00
5
3 01
3 01
5 01
2 10
9 10
1
5 11
3
9 11
8 01
7 10
6
4 01
6 01
7 01
8 00
9 01
1 00
4
8 00
9 10
9 11
8 11
输出
7
5
5
9
-1
8
题目大意及解题思路
大意:
维克多想成为“完美先生”。为此,他需要掌握一定的技能。更确切地说,他有两项技能需要掌握。
维克多有n本书。我读这本书花了他几分钟的时间,并将给他一些(可能没有)所需的两项技能,用长度为2的二进制字符串表示。维克多获得这两项技能所需的最短时间是多少?
输入由多个测试用例组成。第一行包含一个整数(1≤t≤1000)——测试用例的数量。测试用例的描述如下。
每个测试用例的第一行包含一个整数n(1≤n≤2∙10^5)——可用书籍的数量。接着是n行。第i行包含一个正整数m_i(1≤mi≤2∙10^5)和一个长度为2的二进制字符串,其中如果读书i获得Victor skill 1,则s_i1=1,否则s_i1=0,如果读书i获取Victor skill2,则s_i2=1,否则s_i2=0。对于每个测试用例,输出一个整数,表示Victor获得所需技能所需的最小分钟数,如果在阅读了大量书籍后无法获得这两项技能,则输出−1。
思路:
这是一道字符串处理的题,就是让我们在给定的些许两位字符串中,看能否找到两位1?,并且每个字符串有对应的时间m,要求m最小。这里我用结构体来存每本书的信息,包括时间m,和字符串s。将所有字符串按字典序排序,相同的再按时间升序排序。对于每个两位二进制字符串,一共就4种情况(11,10,01,00),而且,我们排完序后就是这样的顺序。然后我们依次找,看是否有前三种字符。
需要注意,不能找到11就结束,因为可能10+01的时间更少。下面就是最后的输出判断。
if (f1 && f2 && sum1 != 0) cout << min(sum1, sum) << endl;
else if (f1 && f2 && sum1 == 0) cout << sum << endl;
else if (sum1 != 0) cout << sum1 << endl;
else cout << "-1" << endl;
AC代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
#define int long long
#define endl '\n'
typedef long long ll;
const int N = 200010;
int a[N], s[N];//预处理前缀和,降低时间复杂度
struct bo {
int m;
string s;
}book[N];
bool cmp(bo a,bo b)
{
if (a.s != b.s)
{
return a.s > b.s;
}
else
{
return a.m < b.m;
}
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> book[i].m >> book[i].s;
}
sort(book, book + n,cmp);
int sum1 = 0;
bool f1= false, f2 = false;
if (book[0].s == "11")
{
sum1 += book[0].m;
}
int sum = 0;
for (int i = 0; i < n; i++)
{
if (book[i].s == "10")
{
sum += book[i].m;
f1 = true;
break;
}
}
for (int i = 0; i < n; i++)
{
if (book[i].s == "01")
{
sum += book[i].m;
f2 = true;
break;
}
}
if (f1 && f2 && sum1 != 0) cout << min(sum1, sum) << endl;
else if (f1 && f2 && sum1 == 0) cout << sum << endl;
else if (sum1 != 0) cout << sum1 << endl;
else cout << "-1" << endl;
}
return 0;
}