Codeforces 653C Bear and Up-Down 【模拟】

本文深入解析了Codeforces竞赛中的Bear and Up-Down序列优化问题,通过模拟方法和条件判断,阐述了解决此类问题的关键步骤与策略,包括特殊情况的处理,如序列长度为奇数时的边界条件、不合法点数量的分析及优化方案的计算。文章详细介绍了从不合法序列到合法序列转换的每一步操作逻辑,以及如何在有限的交换次数内实现序列优化的目标。

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

题目链接:Codeforces 653C Bear and Up-Down

题意:定义 nice 序列为 (i<n)
1, i为奇数,满足 a[i]<a[i+1]
2, i为偶数,满足 a[i]>a[i+1] .
给定一个 n 个数的非nice序列,你只能交换一次。问有多少种方案数得到 nice 序列。

思路:模拟啊。记录不合法的i为cnt。
1,cnt>40 解;
2,cnt==4p2p1==1 && p4p3==1 时交换 p4 p2
3,cnt==3 考虑邻近的 p1p2 或者 p2p3 ,互换位置。
4,cnt==2 考虑 p1p2 是否相邻。
5,cnt==1 暴力枚举与 p1 p1+1 交换。

AC 代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#define PI acos(-1.0)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define fi first
#define se second
#define ll o<<1
#define rr o<<1|1
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int MAXN = 15*1e4 + 10;
const int pN = 1e6;// <= 10^7
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
void add(LL &x, LL y) { x += y; x %= MOD; }
int a[MAXN];
bool judge(int p1, int p2) {
    if(p1 & 1 && p2 & 1) {
        return a[p1] < a[p1+1] && a[p1] < a[p1-1] && a[p2] < a[p2-1] && a[p2] < a[p2+1];
    }
    else if(p1 & 1 && p2 % 2 == 0) {
        return a[p1] < a[p1+1] && a[p1] < a[p1-1] && a[p2] > a[p2+1] && a[p2] > a[p2-1];
    }
    else if(p1 % 2 == 0 && p2 & 1) {
        return a[p1] > a[p1+1] && a[p1] > a[p1-1] && a[p2] < a[p2+1] && a[p2] < a[p2-1];
    }
    else {
        return a[p2] > a[p2+1] && a[p2] > a[p2-1] && a[p1] > a[p1+1] && a[p1] > a[p1-1];
    }
}
int main()
{
    int n; cin >> n;
    for(int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    a[0] = INF;
    if(n & 1) a[n+1] = INF;
    else a[n+1] = -INF;
    int cnt = 0;
    int p1 = -1, p2 = -1, p3 = -1, p4 = -1;
    for(int i = 1; i < n; i++) {
        if(i & 1) {
            if(a[i] >= a[i+1]) {
                if(p1 == -1) p1 = i;
                else if(p2 == -1) p2 = i;
                else if(p3 == -1) p3 = i;
                else p4 = i;
                cnt++;
            }
        }
        else {
            if(a[i] <= a[i+1]) {
                if(p1 == -1) p1 = i;
                else if(p2 == -1) p2 = i;
                else if(p3 == -1) p3 = i;
                else p4 = i;
                cnt++;
            }
        }
    }
    if(cnt > 4) {
        cout << 0 << endl;
        return 0;
    }
    int ans = 0;
    if(cnt == 4) {
        if(p2 - p1 == 1 && p4 - p3 == 1) {
            swap(a[p2], a[p4]);
            ans += judge(p2, p4);
            swap(a[p2], a[p4]);
        }
    }
    else if(cnt == 3) {
        if(p2 - p1 == 1) {
            swap(a[p2], a[p3]); ans += judge(p2, p3); swap(a[p2], a[p3]);
            swap(a[p2], a[p3+1]); ans += judge(p2, p3+1); swap(a[p2], a[p3+1]);
        }
        if(p3 - p2 == 1) {
            swap(a[p1], a[p3]); ans += judge(p1, p3); swap(a[p1], a[p3]);
            swap(a[p1+1], a[p3]); ans += judge(p1+1, p3); swap(a[p1+1], a[p3]);
        }
    }
    else if(cnt == 2) {
        swap(a[p1], a[p2]); ans += judge(p1, p2); swap(a[p1], a[p2]);
        swap(a[p1], a[p2+1]); ans += judge(p1, p2+1); swap(a[p1], a[p2+1]);
        swap(a[p1+1], a[p2]); ans += judge(p1+1, p2); swap(a[p1+1], a[p2]);
        swap(a[p1+1], a[p2+1]); ans += judge(p1+1, p2+1); swap(a[p1+1], a[p2+1]);
        if(p2 - p1 == 1) {
            for(int i = 1; i <= n; i++) {
                if(i == p1 || i == p1+1 || i == p2+1) continue;
                swap(a[i], a[p2]); ans += judge(i, p2); swap(a[i], a[p2]);
                //cout << ans << endl;
            }
        }
    }
    else {
        for(int i = 1; i <= n; i++) {
            if(i == p1 || i == p1 + 1) continue;
            swap(a[i], a[p1]); ans += judge(i, p1); swap(a[i], a[p1]);
            swap(a[i], a[p1+1]); ans += judge(i, p1+1); swap(a[i], a[p1+1]);
        }
        swap(a[p1], a[p1+1]); ans += judge(p1, p1+1); swap(a[p1], a[p1+1]);
    }
    cout << ans << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值