CF变红之路_Educational Codeforces Round 53 (Rated for Div. 2)

本文详细解析了四道ACM竞赛题目,包括签到题、集合维护、区间修改与判断及循环模拟等算法,提供了完整的代码实现与思路分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

昨天打的一场比赛,开始AB题出的很顺,C题不会做(没想到二分的思路),D题出的较慢,一共出了3道题排名1003。今天又重新做了C题发现思路虽然很巧妙,但也是正常的二分思路。

A

签到题,看懂题就会写。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 100;
char s[maxn];
int main() {
    int n;
    cin >> n;
    scanf("%s", s);
    int flag = 1;
    for(int i = 1; i < n; i++) {
        if(s[i] != s[i-1]) {
            cout << "YES" << endl;
            cout << s[i-1] << s[i] << endl;
            flag = 0;
            break;
        }
    }
    if(flag) cout << "NO" << endl;
    return 0;
}

B

用set维护已经拿出的书,在set里的一律输出0然后再找下一个不在set的,遍历的过程中放到set中。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 100;
int a[maxn];
int b[maxn];
int main() {
   int n;
   cin >> n;
   for(int i = 1; i <= n; i++) {
       scanf("%d", &a[i]);
   }
   for(int i = 1; i <= n; i++) {
       scanf("%d", &b[i]);
   }
   set<int> st;
   int cur = 1;
   for(int i = 1; i <= n; i++)
   {
       int tmp = b[i];
       if(st.count(tmp)) {
           printf("0 ");
           continue;
       }
       int ret = 1;
       while(a[cur] != tmp) {
           st.insert(a[cur]);
           cur++;
           ret++;
       }
       cur++;
       printf("%d ", ret);
   }
   return 0;
}

C

题目大意:给出一个字符串,其中每个字符代表移动的方向,起点是原点,然后给出一个坐标,问如果无需修改其中的操作就能到达坐标的话输出0如果在不增减的条件下修改不能到的话输出-1,否则输出修改最小的区间的大小。
思路:输出的0和-1两种情况直接特判就行,然后二分猜最小区间的大小然后放判断,判断的方法也很巧妙,区间和的思路可以极大的减少重复计算量。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = (int)2e5 + 100;

char s[maxn];
ll sx[maxn], sy[maxn];

ll getSum(ll l, ll r, ll* a) {    // 求区间和
    return a[r] - a[l - 1];
}

bool ok(ll x, ll y, ll n) {     // 判断操作n次能否位移量为(x,y)
    x = abs(x);
    y = abs(y);
    return x + y <= n && ((x + y) & 1) == (n & 1);
}

bool judge(ll m, ll n, ll x, ll y) {
    bool flag = false;
    for (ll i = 1; i + m - 1 <= n; i++) {
        ll xx = sx[n] - getSum(i, i + m - 1, sx);
        ll yy = sy[n] - getSum(i, i + m - 1, sy);
        flag |= ok(x - xx, y - yy, m);
        if (flag) return true;
    }
    return false;
}

int main() {
    ll n, x, y;
    scanf("%lld%s%lld%lld", &n, s + 1, &x, &y);
    sx[0] = sy[0] = 0;
    for (int i = 1; i <= n; i++) {
        sx[i] = sx[i - 1];
        sy[i] = sy[i - 1];
        sx[i] += (s[i] == 'R');
        sx[i] -= (s[i] == 'L');
        sy[i] += (s[i] == 'U');
        sy[i] -= (s[i] == 'D');
    }
    if (sx[n] == x && sy[n] == y) {
        cout << 0 << endl;
        return 0;
    }
    if (!ok(x, y, n)) {
        cout << -1 << endl;
        return 0;
    }
    ll l = 0, r = n;
    while (r - l > 1) {
        ll m = (l + r) >> 1;
        if (judge(m, n, x, y)) {
            r = m;
        } else {
            l = m;
        }
    }
    cout << r << endl;
    return 0;
}

D

由于T很大,直接for循环模拟的话必定超时,可以先求和然后判断能走几圈(在不跳的情况下),如果不能不跳,即和大于拥有的金额,那么遍历一次,和减去不能支付的,在判断能走几圈,循环的终止条件是所有的都不能支付。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 100;
ll v[maxn];
bool vis[maxn];
bool cmp(ll a, ll b) {
    return a > b;
}
int main() {
    ll n,have;
    cin >> n >> have;
    ll sum = 0;
    for(ll i = 0; i < n; i++) {
        scanf("%lld", &v[i]);
        sum += v[i];
    }
    ll cnt = n;
    ll ans = 0;
    memset(vis, false, sizeof vis);
    while(cnt) {
        if(sum <= have) {
            ans += (have / sum)*cnt;
            have -= (have / sum) * sum;
        }
        for(int i = 0; i < n; i++) {
            if(vis[i]) continue;
            if(v[i] > have) {
                cnt--;
                vis[i] = true;
                sum-=v[i];
                continue;
            }
            else {
                have -= v[i];
                ans++;
            }
        }
    }
    cout << ans << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值