CF杂题选刷

CF1855B Longest Divisors Interval#

对于任意一个区间 [l,r],一定有 i[1,rl+1],都 j[l,r],使得 ij

因为模 i 意义下的正整数每 i 个一循环,由于 i 小于区间长度,所以在这个区间内一定存在至少一个 0

所以对于区间 [l,r],若 i[l,r] 都满足 in,那么对于 i[1,rl+1] 也一定满足 in

所以对于 i[1,rl+1],都能在 [l,r] 中找到 i 的倍数。

所以问题就转化为从 1 开始枚举,找到 rl+1 合法的最大值。


CF1855B
void Work() {
    cin >> n;

    int ans = 1;
    for(int i = 1;  ; i++) {
        if(n % i != 0) {
            ans = i - 1;
            break;
        }
    }
    cout << ans << "\n";
}

CF1832C Contrast Value#

首先考虑连续相等的一段值,他们的差分的绝对值为 0,不会对序列的权值造成影响,可以直接删去。

再考虑递增和递减的连续段,对于这类连续段,我们把题目中给出的式子展开,发现中间的部分都消去了,只剩下头尾两个元素。

那么中间那些元素就可以删去,只留下最边上两个。


CF1832C
void Work() {
    cin >> n;
    for(int i = 1;i <= n; i++) 
        cin >> a[i];

    int ans = n,tmp = -1;

    for(int i = 1;i < n; i++) {
        if(a[i] == a[i + 1])
            ans --;
        else if(tmp == 0 && a[i + 1] > a[i])
            ans --;
        else if(tmp == 1 && a[i + 1] < a[i])
            ans --;
        else
            tmp = (a[i + 1] < a[i]);
    }
    
    cout << ans << "\n";
    return ;
}

CF1853B Fibonaccharsis#

看到 k 的范围十分吓人,但我们发现,斐波那契数列的第 28 项是 317811,显然已经超过了 2×105 这个范围。

但还要考虑我们这个数列不是真正的斐波那契数列,可以有第一项为 0 的情况,每一项会整体后移一位,所以当 k29 时,答案为 0

那么我们现在只需要考虑 k28 的情况了,直接枚举前两项显然是不现实的,我们考虑换一个思路。

显然,对于这个数列,我们只要有其中两个相邻项的值,就可以递推求出每一项的值。

那我们可以枚举第 k1 项的值,递推求出前两项的值,判断前两项是否合法(非递减且为非负整数序列)。

还有一个思路是:我们可以发现,类斐波那契数列的每一项是能够通过前两项的值表示出来的,可以直接解不定方程。


CF1853B
void Work() {
    cin >> n >> k;
    
    if(k >= 29) {
        cout << "0\n";
        return ;
    }
    
    f[k] = n;
    for(int i = 1;i <= n; i++) {   
        f[k - 1] = i;
        for(int j = k - 2;j >= 1; j--) 
            f[j] = f[j + 2] - f[j + 1];
        
        if(f[2] >= f[1] && f[1] >= 0)
            ans ++;
    }

    cout << ans << "\n";
    return ;
}

CF794C Naming Company#

首先有一个比较显然的贪心思路。

为使得最终字符串的字典序最小,奥列格每次选取自己字典序最小的字符,放在能够放置的最前面位置,伊戈尔每次选取自己字典序最大的字符,也放在能够放置的最前面位置。

但这样的贪心是有问题的,会错在第 6 个测试点。

考虑这样一种状况,奥列格剩下的字符中最小的都已经大于伊戈尔手中最大的,那么如果奥列格再往最前面放显然就是错的了。

这种状况下奥列格怎么最优操作呢?他可以把自己的字符往后放,这样伊戈尔就不得不把他小于奥列格的字符往前放。

那么在这种条件下,二者的最优策略就是把自己的字符从后往前放。

所以当奥列格仍然有小于伊戈尔的字符时,采取第一种策略,否则采取第二种策略。

具体代码可以用 deque 维护,支持取头尾元素,十分的方便。

时间复杂度 O(n)


CF794C
#include <bits/stdc++.h>

using namespace std;

int n;

string s,t;

deque<char> q1,q2;

int main() {
    cin >> s >> t;

    n = s.size();
    sort(s.begin(),s.end());

    sort(t.begin(),t.end());
    reverse(t.begin(),t.end());

    for(int i = 0;i < (n + 1) / 2; i++) 
        q1.push_back(s[i]);
    
    for(int i = 0;i < n / 2; i++)
        q2.push_back(t[i]);

    string ansl = "",ansr = "";
    
    bool flag = 0;
    for(int i = 1;i <= n; i++) {
        if(i % 2) {
            if(!q2.empty() && q1.front() >= q2.front())
                flag = 1;
            
            if(flag) {
                ansr += q1.back();
                q1.pop_back();
            }
            else {
                ansl += q1.front();
                q1.pop_front();
            }
        }
        else {
            if(!q1.empty() && q1.front() >= q2.front())
                flag = 1;
            
            if(flag) {
                ansr += q2.back();
                q2.pop_back();
            }
            else {
                ansl += q2.front();
                q2.pop_front();
            }
        }
    }

    reverse(ansr.begin(),ansr.end());

    string ans = ansl + ansr;

    cout << ans;
    return 0;    
}

作者:白简

出处:https://www.cnblogs.com/baijian0212/p/codeforces.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   -白简-  阅读(27)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu