【atcoder】ABC练习记录DAY1

写在前面:
因为最近cf打得非常惨烈,也发现了自己在暴力模拟题的思维能力和代码实现能力严重欠缺(尤其是代码实现能力,这也造成了我在组队赛中心理上非常抗拒上机写题)
受到大佬这篇文章的启发,决定开始刷atcoder的ABC中的 problem B、C,希望在大二开学前cf能顺利打上1400+
之后会对每天刷的atcoder进行记录以监督自己坚持练习

ABC310

B - Strictly Superior

题意

给出每个商品的价格和包含的功能,问是否有一个商品严格优于另一个商品
i 严格优于 j 必须满足下列条件之一:

  • i 比 j 便宜,i 的功能包含了 j 的所有功能
  • i 和 j 价格一样,i 的功能包含 j 的所有功能且比 j 的功能多

思路

暴力,判断当前的两个物品是否满足上述条件

代码

原始代码
#include <bits/stdc++.h>

using namespace std;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    int n, m;
    cin >> n >> m;
    vector<int> price(n);
    vector<int> func_num(n);
    int func[110][110];
    for (int i = 0; i < n; i ++ ) 
    {
        cin >> price[i] >> func_num[i];
        for (int j = 0; j < func_num[i]; j ++ ) cin >> func[i][j];
    }

    for (int i = 0; i < n; i ++ )
    {
        for (int j = 0; j < n; j ++ )
        {
            if (i == j) continue;
            // 判断i是否严格优于j
            if (price[i] > price[j]) continue;
            else if (price[i] == price[j])
            {
                if (func_num[i] <= func_num[j]) continue;
                else
                {
                    int l = 0, r = 0;
                    while (l < func_num[i] && r < func_num[j])
                    {
                        if (func[i][l] > func[j][r]) break;
                        else if (func[i][l] == func[j][r]) l ++, r ++ ;
                        else l ++ ;
                    }
                    if (r == func_num[j])
                    {
                        cout << "Yes" << endl;
                        return 0;
                    }
                }
            }
            else
            {
                if (func_num[i] < func_num[j]) continue;
                else
                {
                    int l = 0, r = 0;
                    while (l < func_num[i] && r < func_num[j])
                    {
                        if (func[i][l] > func[j][r]) break;
                        else if (func[i][l] == func[j][r]) l ++, r ++ ;
                        else l ++ ;
                    }
                    if (r == func_num[j])
                    {
                        cout << "Yes" << endl;
                        return 0;
                    }
                }
            }
        }
    }
    cout << "No" << endl;
}
优化代码

这里参考了jls的代码,发现自己还是思考少了导致代码就很长…

#include <bits/stdc++.h>

using namespace std;

const int N = 110;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    int n, m;
    cin >> n >> m;
    vector<int> price(n);
    vector<bitset<N>> func(n);
    for (int i = 0; i < n; i ++ ) 
    {
        int x;
        cin >> price[i] >> x;
        for (int j = 0; j < x; j ++ )
        {
            int k;
            cin >> k;
            func[i][k - 1] = 1;
        }
    }

    for (int i = 0; i < n; i ++ )
    {
        for (int j = 0; j < n; j ++ )
        {
            if (price[i] <= price[j] && (func[i] & func[j]) == func[j] && (price[i] < price[j] || func[i] != func[j]))
            {
                cout << "Yes" << endl;
                return 0;
            }
        }
    }
    cout << "No" << endl;
}

C - Reversible

题意

正着看反着看一样的字符串算作同一种字符串,给出若干个字符串,问有多少种

思路

我的代码里用了map来存储,实际上好像也没有必要,只需要一个有查找函数的容器就可以了,先把所有字符串存进去,再从头遍历每一个字符串,记录下已经遍历过的,统计种类数即可(正反算同一种)

代码

#include <bits/stdc++.h>

using namespace std;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    
    int n;
    map<string, int> m;
    cin >> n;
    vector<string> ss(n);
    for (int i = 0; i < n; i ++ )
    {
        string s;
        cin >> s;
        ss[i] = s;
        if (m.find(ss[i]) == m.end()) m[ss[i]] = 1;
        else m[ss[i]] ++ ;
    }
    int ans = 0;
    for (int i = 0; i < n; i ++ )
    {
        if (m[ss[i]] != 0)
        {
            string s = ss[i];
            m[s] = 0; // 表示该种情况已经计算过
            reverse(s.begin(), s.end());
            m[s] = 0;
            ans ++ ;
        }
    }
    cout << ans;
}

ABC309

B - Rotate

题意

给出一个二维数组,把最外面一圈顺时针转一下再输出

思路

记录下四个顶点的,然后直接挪

代码

#include <bits/stdc++.h>

using namespace std;

const int N = 110;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    int n;
    cin >> n;
    char g[N][N];
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < n; j ++ )
            cin >> g[i][j];

    char a = g[0][0], b = g[0][n - 1], c = g[n - 1][0], d = g[n - 1][n - 1];
    for (int i = n - 1; i > 0; i -- )
    {
        g[0][i] = g[0][i - 1];
        g[i][n - 1] = g[i - 1][n - 1];
    }
    for (int i = 0; i < n - 1; i ++ )
    {
        g[n - 1][i] = g[n - 1][i + 1];
        g[i][0] = g[i + 1][0];
    }
    g[0][1] = a, g[1][n - 1] = b, g[n - 2][0] = c, g[n - 1][n - 2] = d;

    for (int i = 0; i < n; i ++ )
    {
        for (int j = 0; j < n; j ++ )
            cout << g[i][j];
        cout << endl;
    }
}

C - Medicine

题意

从第一天开始,告诉你吃多少药,每种药每天吃多少片、吃多少天,问多少天之后吃的药片个数小于等于给定值 k

思路

按天数从大到小排列,用 sum 累加当前吃的药的片数,直到大于 k,输出这一天的后一天

代码

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

typedef pair<int, int> PII;

bool cmp(PII a, PII b)
{
    return a.first > b.first;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    int n, k;
    cin >> n >> k;
    i64 sum = 0;
    vector<pair<int, int>> messages(n);
    for (int i = 0; i < n; i ++ )
    {
        int a, b;
        cin >> a >> b;
        messages[i] = make_pair(a, b);
    }
    sort(messages.begin(), messages.end(), cmp);
    if (k < messages[0].second)
    {
        cout << messages[0].first + 1;
        return 0;
    }
    for (int i = 0; i < n; i ++ )
    {
        sum += messages[i].second;
        if (sum > k)
        {
            cout << messages[i].first + 1;
            return 0;
        }
    }
    cout << 1;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Texcavator

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值