AtCoder Beginner Contest 247部分题解

本篇题解只是记录我的做题过程代码,不提供最优解
(另外这里所有的时间复杂度都只分析单个样例,不算 t t t的时间复杂度)

A

点击此处查看对应的题目.
本题设计算法:模拟
直接将字符串向后推移一位即可。

时间复杂度 O ( n ) O(n) O(n)

#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <cmath>
using namespace std;
typedef long long ll;
const ll N = 110;
int a[N];

int main()
{
    string s;
    cin >> s;
    int n = s.size();
    for (int i = 0;i < n;i ++ ) {
        a[i + 1] = s[i] - '0';
    } 
    a[0] = 0;
    for (int i = 0;i < n;i ++ ) {
        cout << a[i];
    }
    puts("");
    return 0;
}


B

点击此处查看对应的题目.
本题设计算法:map统计

本题主要问题是判重,只要用个map统计字符串出现的次数就可以实现,但切记当一行字符串相同时,只能算一个,不然后面判断不出来。

时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)

#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <cmath>
using namespace std;
typedef long long ll;
const int N = 10010;
map<string,int> m;
string s[N],t[N];

int main()
{
    int n;
    cin >> n;
    for (int i = 1;i <= n;i ++ ) {
        string a,b;
        cin >> a >> b;
        s[i] = a,t[i] = b;
        if (a == b) m[a] ++;
        else m[a] ++,m[b] ++;
    }
    for (int i = 1;i <= n;i ++ ) {
        string a = s[i],b = t[i];
        if ((m[a] > 1 && m[b] > 1)) {
            cout << "No" << '\n';
            return 0;
        }
    }

    puts("Yes");
    return 0;
}

C

点击此处查看对应的题目.
本题设计算法:二叉树遍历
不难发现,本题的输出,遵循二叉树中序遍历的结果

时间复杂度 O ( 2 n ) O(2^n) O(2n)

#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <cmath>
using namespace std;
typedef long long ll;
const int N = 10010;
int n;

void dfs(int u) 
{
    if (u == 0) return;
    dfs(u - 1);
    cout << u << ' ';
    dfs(u - 1);
}
int main()
{
    cin >> n;
    dfs(n);
    puts("");

    return 0;
}


D

点击此处查看对应的题目.
本题设计算法:队列

本题的要求大致是要从后添加球,从前取出去球。

所以,从本题的要求可以看出,这符合队列的特性,我们可以用队列来实现这一系列的操作。

时间复杂度 O ( q ∗ ( c / d ) ) O(q * (c / d)) O(q(c/d))

#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PLL;
const int N = 10010;
queue<PLL> qe;
ll q,l,r;

int main()
{
    cin >> q;
    while (q -- ) {
        ll op,x,c;
        cin >> op;
        if (op == 1) {
            cin >> x >> c;
            qe.push({c,x});
        }else {
            cin >> c;
            ll sum = 0;
            while (c) {//从队列前端向后取球,直到将c取完为止
                ll d = min(c,qe.front().first);
                sum += 1ll * d * qe.front().second;
                qe.front().first -= d;
                c -= d;
                if (!qe.front().first) qe.pop();
            }
            cout << sum << '\n';
        }
    }
    return 0;
}

E

点击此处查看对应的题目.
本题设计算法:状态压缩dp

本题我采用了 dls 的代码,思路已经都写在代码里了。详细见代码注释。

时间复杂度 O ( 4 ∗ n ) O(4 * n) O(4n)

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10,INF = 1e9;
ll dp[N][2][2];//表示前i个数(以第i个数结尾),是否出现过x或是是否出现过y的所有方案数量
int n,x,y;
int a[N];

int main()
{
    scanf("%d%d%d",&n,&x,&y);
    for (ll i = 1;i <= n;i ++ ) scanf("%d",&a[i]);

    ll res = 0;
    for (int i = 1;i <= n;i ++ ) {
        if (a[i] > x || a[i] < y) continue;//排除不在区间范围的数

        int is_x = (a[i] == x),is_y = (a[i] == y);
        dp[i][is_x][is_y] ++;
        //当前状态的与过去状态取并集
        for (int j = 0;j < 2;j ++ ) {
            for (int k = 0;k < 2;k ++ ) {
                dp[i][is_x | j][is_y | k] += dp[i - 1][j][k];//只要过去的状态或当前的状态有1,那么当前的状态就是1
            }
        }
        res += dp[i][1][1];
    }
    /*
    for (int i = 1;i <= n;i ++ ,puts("")) {
        for (int j = 0;j < 2;j ++ ) {
            for (int k = 0;k < 2;k ++ ) {
                cout << dp[i][j][k] << ' ';
            }
        }
    }
    */
    printf("%lld\n",res);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

marvel121

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

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

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

打赏作者

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

抵扣说明:

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

余额充值