Codeforces Round #807 (Div. 2) A-C

目录

题目

A. Mark the Photographer

题意:

思路:

code:         

B. Mark the Dust Sweeper

题意:

思路:

code:

C. Mark and His Unfinished Essay

题意:

思路:

code:

总结:


题目

A. Mark the Photographer

题意:

给你 2*n个数, 一个数x, 要求把这2n个数分成2组, 保证其中一组每个数都比另一组的数大x, 即b_i-a_i>=x.

思路:

把这2n个数sort下, 截取成两段, 逐个对应判断是否存在b_i-a_i>=x即可, 有点贪心思想.

code:         

/**
 *    author:  CurleyD
 *    created: 07.15.2022 21:35:34
**/
#include <bits/stdc++.h>
#define endl '\n'
#define IO ios::sync_with_stdio(false); cin.tie(nullptr);
using namespace std;
typedef long long LL;
//#define LOCAL
//#define int LL
//head

const int INF = 0x3f3f3f3f;
const int N = 1e5 + 10;
int T, n, m, x;

int a[N];

void solve() {
    cin >> n >> x;
    for (int i = 1; i <= n * 2; i++) 
        cin >> a[i];
    sort(a+1,a+1+2*n);
    for (int i = 1; i <= n; i++) {
        if (a[i+n] - x >= a[i]) {
            continue;
        }
        else {
            cout << "NO\n";
            return;
        }
    }
    cout<<"YES\n";
}

signed main() {
    IO;
    #ifdef LOCAL
        freopen("out.txt","w",stdout);
    #endif
    cin >> T;
    while(T--) {solve();}
    return 0;
}

B. Mark the Dust Sweeper

题意:

题目给的题意不明确, 大概意思就是给你个n个正数, 对于 1~n 你可以任选 i, j在这范围之内

进行 ai = ai - 1, aj = aj + 1, (需要保证为正), 问你最少多少次使得 1~n-1的数全为0? 描述的可能不太清晰...

思路:

根据下面的提示来看似乎不能一直选j=n???

观察样例 + 猜想 + 结合实际吸尘器不能跳着吸只能顺着推可知, ans = (1~n-1的ai) + (1~n-1相邻的正数相差的0的数量即间隔数);

不知道怎么证明???

code:

/**
 *    author:  CurleyD
 *    created: 07.15.2022 21:57:42
**/
#include <bits/stdc++.h>
#define endl '\n'
#define IO ios::sync_with_stdio(false); cin.tie(nullptr);
using namespace std;
typedef long long LL;
//#define LOCAL
//#define int LL
//head

const int INF = 0x3f3f3f3f;
const int N = 2e5 + 10;
int T, n, m;

int a[N];

void solve() {
    cin >> n;
    LL res = 0;
    LL cnt = 0;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    bool f = 0;
    for (int i = 1; i <= n - 1; i++) {
        if (a[i] != 0) {
            f = 1;
            res = res + a[i] + cnt;
            cnt = 0;
        }
        if (a[i] == 0 && f) {
            cnt ++;
        }
    }    
    res += cnt;
    cout << res << endl;
}

signed main() {
    IO;
    #ifdef LOCAL
        freopen("out.txt","w",stdout);
    #endif
    cin >> T;
    while(T--) {solve();}
    return 0;
}

C. Mark and His Unfinished Essay

题意:

给你个长度n的字符串, 每次可截取l, r 放在字符串的末尾使得字符串的长度跟着增长, 进行完上述操作给你k个询问, 每个询问给你个位置, 输出增长完的字符串的对应字符是什么?

思路:

l, r 都是1e18显然模拟会超时, 开始一直想着hash来做, 但是我不会  

我的做法可能会fst...但pretest过了

通过他最大每次可能给30次修改, 想到可以溯源每个pos映射在原来s串的位置

具体解释下的话如下:

一个样例:n=4,m=3,k=1,s="mark"

4 3 1
mark
1 4
5 7
3 8
10

三次修改, 一次查询

我们用newl表示新增区间l, newr同理, len表示新增区间的长度.

markmark l = 1, r = 4, newl = 5, newr = 8, len = 4

markmarkmar  l = 5, r = 7, newl = 9, newr = 11, len = 3

markmarkrkmark  l = 3, r = 8, newl = 12, newr = 17, len = 6

对于pos = 10, 它是由l=5,r=7区间变成的, 则pos相当于其中的 x = 6!

因此我们可以把pos设置成pos = 6!!!

同理pos=6 -> pos=newl - l + pos!!!

因此我们的过程大致为:

1)读入s,n,m,k, 设置SZ=s.size() (以后要更新会增长)

2)读入l, r 对于每组l,r, 记录其新老l,r到结构体数组p中 即len, 更新SZ

3)sort下p, 方便之后找, 当然不sort估计也行

4)查询过程, 对于每个pos, 进行溯源, 直到pos 在 1~n之间为止!

得解

要是没有fst那证明这个做法可行的, 但感觉应该是对的.

code:

/**
 *    author:  CurleyD
 *    created: 07.15.2022 22:08:18
**/
#include <bits/stdc++.h>
#define endl '\n'
#define IO ios::sync_with_stdio(false); cin.tie(nullptr);
using namespace std;
typedef long long LL;
//#define LOCAL
//#define int LL
//head

const int INF = 0x3f3f3f3f;
const int N = 1e5 + 10;
int T, n, m, k;

LL l, r, pos;

struct node{
    LL l, r, len;
    LL x, y;
}p[55];

bool cmp(node a, node b) {
    return a.l < b.l;
}

void solve() {
    string s;
    cin >> n >> m >> k;
    cin >> s;
    LL SZ = s.size();
    s.insert(s.begin(),'#');
    for (int i = 1; i <= m; i++) {
        cin >> l >> r;
        LL len = r - l + 1;
        //老区间
        p[i].x = l;
        p[i].y = r;
        //新区间
        p[i].l = SZ + 1;
        p[i].r = SZ + len;
        p[i].len = len;
        SZ += len;
        //cout<<p[i].l << " " << p[i].r << endl;
    }
    sort(p + 1, p + 1 + m, cmp);
    for (int q = 1; q <= k; q++) {
        cin >> pos;
        while (pos > n) {
            for (int i = 1; i <= m; i++) {
                if (p[i].l <= pos && p[i].r >= pos) {
                    pos = p[i].x + pos - p[i].l;
                    // cout << pos << endl;
                    break;
                }
            }
        }
        cout<<s[pos]<<endl;
    }
}

signed main() {
    IO;
    #ifdef LOCAL
        freopen("out.txt","w",stdout);
    #endif
    cin >> T;
    while(T--) {solve();}
    return 0;
}



/*
5->7    
9->11  10 - 9 + 5 -> 6
*/

总结:

1)简单题思路形成慢,

2)过于依赖翻译

3)有时候写一半发现漏掉条件/读了假题 ->这次的B

4)会在细节出问题, ->这次的C, 结构体里忘记开LL, len忘开LL导致出现负数溢出, 血亏.

毕竟是菜狗, 第一次赛时出c已经挺高兴了, D似乎是个dp? 看了下tourist的不是dp...

update:

开测了QAQ

没FST, 好耶LOL

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值