A - Order Something Else A - Order Something Else
题目大意
计算 Takahashi 最少需要支付多少钱才能获得 AtCoder Drink。AtCoder Drink 可以按照原价 P 日元购买,也可以使用折扣券以 Q 日元的价格购买,但必须再额外购买 N 道菜品中的一道才能使用折扣券。每道菜品的价格分别为 D1, D2, …, DN。
思路分析
为了使总支付金额最小,Takahashi 需要比较两种情况:
- 不使用折扣券时,直接按照原价购买 AtCoder Drink,总支付金额为 P。
- 使用折扣券时,选择一道最便宜的菜品 Di,并将折扣券与 AtCoder Drink 一起购买,总支付金额为 (Di + Q)。
通过比较这两种情况的总支付金额,取较小值作为最终结果。
时间复杂度
O(NlogN)
代码
#include<bits/stdc++.h>
using namespace std;
const int N=110;
int main()
{
int a[N];
int n,p,q;
cin>>n>>p>>q;
for(int i=0;i<n;i++)
{cin>>a[i];
}
sort(a,a+n);
int x=a[0];
int res=min(x+q,p);
cout<<res<<endl;
return 0;
}
B - Strictly SuperiorB - Strictly Superior
题目大意
给定N种产品,每种产品都有一个价格和一些功能。需要判断是否存在某个产品严格优于其他产品。如果存在两个产品i和j,满足以下条件之一,则认为产品i严格优于产品j:
- 产品i的价格高于产品j的价格。
- 产品j具有产品i所有的功能,或者产品i缺少产品j拥有的某些功能。
思路分析
因为数据范围较小,可以使用暴力解法来解决这个问题。遍历所有可能的产品对(i, j),并检查是否满足上述条件。如果找到了满足条件的产品对,则输出"Yes",否则输出"No"。
算法步骤:
遍历所有产品对(i, j)。
对于每个产品对,根据条件进行判断:
如果p[i] > p[j],则说明产品i的价格严格高于产品j的价格,输出"Yes",结束程序。
如果p[i] == p[j],并且d[j] > d[i],则说明产品j拥有比产品i更多的功能,输出"Yes",结束程序。
否则,继续遍历下一个产品对。
如果遍历所有产品对后仍未找到满足条件的产品对,则输出"No"。
时间复杂度
O(N2)
代码
#include <iostream>
using namespace std;
int main() {
int m, n;
cin >> n >> m;
int p[107], d[107], ks[107][107];
for (int i = 1; i <= n; i++) {
cin >> p[i] >> d[i];
for (int j = 1, t; j <= d[i]; j++) {
cin >> t; // 读取功能的编号
ks[i][t] = 1; // 将第i个产品具有的该功能标记为1
}
}
for (int i = 1; i <= n; i++) { // 外层循环遍历所有可能的产品对(i, j)
for (int j = 1; j <= n; j++) {
if (p[i] >= p[j]) { // 判断第i个产品的价格是否大于等于第j个产品的价格
bool flg = true;
for (int k = 1; k <= m; k++) { // 内层循环遍历每个功能
if (ks[i][k] > ks[j][k]) { // 判断第i个产品是否具有第j个产品缺少的功能
flg = false; // 如果第i个产品具有第j个产品缺少的功能,则将标志位flg设为false
break;
}
}
if (flg) { // 如果第j个产品具有第i个产品的所有功能,并且满足以下条件之一:
if (p[i] > p[j] || (p[i] == p[j] && d[j] > d[i])) { // 1. 第i个产品价格高于第j个产品,或者2. 价格相等时,第j个产品功能数量大于第i个产品
cout << "Yes" << endl;
return 0;
}
}
}
}
}
cout << "No" << endl;
return 0;
}
C - ReversibleC - Reversible
题目大意
一组有重复序列的字符串,两个字符串若正序或逆序相同,则两字符串相同,问有多少根不同的串
思路分析
题目要求找出N根棍子中不同的棍子数量。首先需要使用一个数据结构来存储已经出现过的棍子,以便进行比较。可以使用集合(set)来存储棍子的字符串。
- 读入字符串s表示当前棍子上球的序列。
- 如果集合T中没有与s相等的元素(即count(s)等于0),说明这是一个新的棍子,则将ans加一。
- 将字符串s插入到集合T中。
- 将字符串s反转后插入到集合T中,以考虑逆序情况。
时间复杂度
O(NMlogN)
首先,需要遍历N个棍子,对于每个棍子,需要进行字符串的比较和插入操作。集合的插入和查找操作的平均时间复杂度为O(logN),而字符串的比较和反转操作的时间复杂度取决于字符串的长度,设为O(M)。因此,总体时间复杂度为O(NMlogN)。
代码
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
int main(void)
{
int n;
cin >> n;
int ans = 0;
set<string> T;
string s;
for(int i = 1; i <= n; i++){
cin >> s;
if(T.count(s) == 0) ans++; // 如果集合T中没有与s相等的元素,则将ans加一
T.insert(s); // 将字符串s插入到集合T中
reverse(s.begin(), s.end()); // 反转字符串s
T.insert(s); // 将反转后的字符串s插入到集合T中,以考虑逆序情况
}
cout << ans << endl;
return 0