AtcoderABC301场

A - Order Something Else A - Order Something Else

AtcoderABC301场_第1张图片AtcoderABC301场_第2张图片

题目大意

计算 Takahashi 最少需要支付多少钱才能获得 AtCoder Drink。AtCoder Drink 可以按照原价 P 日元购买,也可以使用折扣券以 Q 日元的价格购买,但必须再额外购买 N 道菜品中的一道才能使用折扣券。每道菜品的价格分别为 D1, D2, …, DN。

思路分析

为了使总支付金额最小,Takahashi 需要比较两种情况:

  • 不使用折扣券时,直接按照原价购买 AtCoder Drink,总支付金额为 P。
  • 使用折扣券时,选择一道最便宜的菜品 Di,并将折扣券与 AtCoder Drink 一起购买,总支付金额为 (Di + Q)。
    通过比较这两种情况的总支付金额,取较小值作为最终结果。

时间复杂度

O(NlogN)

代码

#include
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

AtcoderABC301场_第3张图片AtcoderABC301场_第4张图片AtcoderABC301场_第5张图片

题目大意

给定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 
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

AtcoderABC301场_第6张图片AtcoderABC301场_第7张图片AtcoderABC301场_第8张图片

题目大意

一组有重复序列的字符串,两个字符串若正序或逆序相同,则两字符串相同,问有多少根不同的串

思路分析

题目要求找出N根棍子中不同的棍子数量。首先需要使用一个数据结构来存储已经出现过的棍子,以便进行比较。可以使用集合(set)来存储棍子的字符串。

  • 读入字符串s表示当前棍子上球的序列。
  • 如果集合T中没有与s相等的元素(即count(s)等于0),说明这是一个新的棍子,则将ans加一。
  • 将字符串s插入到集合T中。
  • 将字符串s反转后插入到集合T中,以考虑逆序情况。

时间复杂度

O(NMlogN)
首先,需要遍历N个棍子,对于每个棍子,需要进行字符串的比较和插入操作。集合的插入和查找操作的平均时间复杂度为O(logN),而字符串的比较和反转操作的时间复杂度取决于字符串的长度,设为O(M)。因此,总体时间复杂度为O(NMlogN)。

代码

#include 
#include 
#include 
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

你可能感兴趣的:(算法)