Codeforces Round #744 (Div. 3)部分题解

开始前,我还是想提前庆祝一下,第一次写这么多题的题解QwQ~~。

A

点击此处查看对应的题目.
本题模拟
直接统计a,b,c 的字母数量,最后判断c数量是否等于a+b数量。

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

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10,INF = 1e9 + 1;
int a,b,c;

void solve()
{
   a = 0,b = 0,c = 0;
   string s;
   cin >> s;
   for(int i = 0;i < s.size();i ++){
        if(s[i] == 'A') a ++;
        if(s[i] == 'B') b ++;
        if(s[i] == 'C') c ++;
    }
   if(b == a + c) puts("Yes");
   else puts("No");
}
int main()
{
    int t;
    cin >> t;
    while(t--){
         solve();
    }
    return 0;
}



B

点击此处查看对应的题目.
本题涉及算法:排序
本题是要对这串数据进行排序。

我的想法是,先对原序列排序成一个新序列,再将新序列与原序列对比,遍历所有序列,确定原序列与新序列相等元素的移动区间,记录每一个移动的区间,并改变序列本身。

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

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10,INF = 1e9 + 1;
int a[N],b[N],c[N];
struct S
{
    int l,r,d;
};

void solve()
{
   vector<S> res;
   int n;
   cin >> n;
   for(int i = 1;i <= n ;i ++){
        cin >> a[i];
        b[i] = a[i];
   }

    sort(b + 1,b + n + 1);

    for(int i = n;i >= 1;i --) {
        int k = 0;
        for(int j = i;j >= 1;j --)
            if(a[j] == b[i]){
                k = j;
                break;
            }

        if(k && k != i){
            res.push_back({k,i,1});
            for(int d = 1;d <= k - 1;d ++) c[d] = a[d];
            for(int d = k;d <= n - 1;d ++) c[d] = a[d + 1];
            c[n] = a[k];
            memcpy(a,c,sizeof(c));
        }

    }

    cout << res.size() << '\n';
    for(int i = 0;i < res.size();i ++) cout << res[i].l << " " << res[i].r << " " << res[i].d << '\n';
}
int main()
{
    int t;
    cin >> t;
    while(t--){
        solve();
    }
    return 0;
}



C

点击此处查看对应的题目.
本题模拟
本题是看所有是否能你模拟出来的所有√勾是否能对标记的单元格进行所有覆盖,我这里模拟了所有 ′ ∗ ′ '*' 元素不断向上两边延伸的过程就行(这里我用了递归来进行延伸的操作)。

时间复杂度 O ( n 2 ∗ m ) O(n^2*m) O(n2m)

#include<bits/stdc++.h>
using namespace std;
const int N = 110,INF = 1e9;
char g[N][N];
bool st[N][N];
int n,m,k;
struct Node
{
    int a,b,c;
};
vector<Node> v;

bool judge()
{
    for(int i = 1;i <= n;i ++)
        for(int j = 1;j <= m;j ++)
            if(!st[i][j] && g[i][j] == '*')
                return false;
    return true;
}
void init()
{
    for(int i = 0;i < N;i ++)
        for(int j = 0;j < N;j ++){
            g[i][j] = '.';
            st[i][j] = false;
        }
}
int dg(int x,int y1,int y2,int h)
{
    if(g[x][y1] != '*' || g[x][y2] != '*'){
        if(h >= k){
            for(int i = 0;i < v.size();i ++)
                st[v[i].a][v[i].b] = true,st[v[i].a][v[i].c] = true;
            return 1;
        }
        return 0;
    }
    v.push_back({x,y1,y2});
    dg(x - 1,y1 + 1,y2 - 1,h + 1);
}
void solve()
{
    cin >> n >> m >> k;
    init();
    for(int i = 1;i <= n;i ++)
        for(int j = 1;j <= m;j ++)
            cin >> g[i][j];

    int maxn = -INF;
    for(int i = 1;i <= n;i ++)
        for(int j = 1;j <= m;j ++)
            if(g[i][j] == '*'){
                int t = dg(i - 1,j + 1,j - 1,0);
                if(t) st[i][j] = true;
                v.clear();
            }

    if(judge()) puts("Yes");
    else puts("No");
}
int main()
{
    int t;
    cin >> t;
    while (t -- ){
        solve();
    }
    return 0;
}

D

点击此处查看对应的题目.
本题涉及算法:贪心
本题应该要贪心的选取两个最大的元素,将这两个元素减1,最后达到整个序列只有一个非0元素的目的。

这里用优先队列来进行数据储存,以便于进行实时排序。选取队列队头即为最大值。

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

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N = 1e5 + 10;

void solve()
{
    priority_queue<PII, vector<PII>, less<PII>> q;
    vector<PII> res;
    int n;
    cin >> n;

    for(int i = 1;i <= n;i ++){
        int x;
        cin >> x;
        if(x) q.push({x,i});
    }

    while(q.top().first && q.size() > 1){
        int x = q.top().first;
        int index_x = q.top().second;
        q.pop();

        int y = q.top().first;
        int index_y = q.top().second;
        q.pop();

        x --,y --;
        res.push_back({index_x,index_y});

        if(x > 0) q.push({x,index_x});
        if(y > 0) q.push({y,index_y});
    }

    cout << res.size() << '\n';
    if(res.size()){
        for(int i = 0;i < res.size();i ++) cout << res[i].first << " " << res[i].second << '\n';
    }
}
int main()
{
    int t;
    cin >> t;
    while(t -- ){
        solve();
    }
    return 0;
}

E1

点击此处查看对应的题目.
本题涉及算法:双端队列 + 贪心
简单模拟题意即可,贪心地从前后加入元素即可。

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

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10,INF = 1e9 + 7;
int a[N];

void solve()
{
    int n;
    deque<int> q;
    cin >> n;

    for(int i = 0;i < n;i ++){
        int x;
        cin >> x;
        if(q.empty() || x < q.front()) {
            q.push_front(x);
        }else {
            q.push_back(x);
        }
    }
    for(auto it : q) cout << it << " ";
    puts("");
}
int main()
{
    int t;
    cin >> t;
    while(t -- ){
        solve();
    }
    return 0;
}


  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

marvel121

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

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

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

打赏作者

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

抵扣说明:

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

余额充值