Codeforces Round 987 (Div. 2)(A-D)

感觉板子题没写出来,算了,半退了

A - Penchick and Modern Monument

思路

找到最长上升子序列即可,数据小无脑n2即可 

代码 

void solve() {
    ll n;
    cin >> n;
    vector<ll>arr(n + 2);
    for (int i = 1; i <= n; i++) {
        cin >> arr[i];
    }
    vector<ll>dp(n + 2,1);
    ll ans = 1;
    for (int i = 1; i <= n; i++) {
        for (int j = i + 1; j <= n; j++) {
            if (arr[j] >= arr[i]) {
                dp[j] = max(dp[j], dp[i] + 1);
            }
            ans = max(ans, dp[j]);
       }
    }
    cout << n-ans;
}

B - Penchick and Satay Sticks 

思路 

因为只有差距1才能才能转化,手推就会发现3以上就不行了,直接算一遍即可

代码 

void solve() {
    ll n;
    cin >> n;
    vector<ll>arr(n + 2);
    for (int i = 1; i <= n; i++) {
        cin >> arr[i];
    }
    for (int i = 1; i < n; i++) {
        if (arr[i + 1] + 1 == arr[i]) {
            swap(arr[i], arr[i + 1]);
        }
    }
    for (int i = 1; i <= n; i++) {
        if (arr[i] != i) {
            cout << "NO";
            return;
        }
    }
    cout << "YES";
}

 C - Penchick and BBQ Buns 

思路 

感觉是个人都会错一发

首先对于n为偶数无脑112233就可以了

奇数的情况,我们需要产生一个奇数的集合,把剩下的编成偶数即可,我们手打个样例就会发现,最小的就是34,也就是3*3+4*4==5*5,然后发现这个之后就无脑做即可

代码 

 

ll arr[200020];
void init() {
    arr[1] = 1;
    arr[10] = 1;
    arr[26] = 1;
    arr[11] = 2;
    arr[27] = 2;
}
void solve() {
    ll n;
    cin >> n;
    if (n % 2 == 0) {
        for (int i = 1; i <= n / 2; i++) {
            cout << i << " " << i << " ";
        }
        return;
    }
    if (n < 27) {
        cout << "-1";
        return;
    }
    ll top = 6;
    for (int i = 1; i <= n; i++) {
        if (arr[i]) {
            cout << arr[i] << " ";
        }
        else {
            cout << top / 2 << " ";
            top++;
        }
    }
    
}

D-

思路

感觉也比较板子,赛时把brr写成arr写红了,

其实就是把最大值进行排序,首先对于最大值右边的数字肯定能跳到最大值上面,那么继续往下一个走,会出现两个情况,已经被标记过,跳过,没有被标记过,也就是在最大值左边,这个时候也会出现两个情况,能够跳到上一个最大值的左边,那么当前点的答案就是上一个最大值,不能的话,就是当前点到上一次的最大值,维护一下区间即可

代码

struct node {
    ll id, x;
    node() {};
    node(ll a, ll b) {
        this->id = a;
        this->x = b;
    }
};
node arr[500050];
bool cmp(node a, node b) {
    if (a.x != b.x) {
        return a.x > b.x;
    }
    else {
        return a.id > b.id;
    }
}
void solve() {
    ll n;
    cin >> n;
    vector<ll>dp(n + 2);
    vector<ll>brr(n + 2);
    for (int i = 1; i <= n; i++) {
        cin >> arr[i].x;
        brr[i] = arr[i].x;
        arr[i].id = i;
    }
    sort(arr + 1, arr + 1 + n, cmp);
    ll r = arr[1].id;
    ll ans = arr[1].x;
    
    ll minn = 1e18;
    for (int i = r; i <= n; i++) {
        dp[i] = ans;
        minn = min(minn, brr[i]);
    }
    
    for (int i = 2; i <= n; i++) {
        if (dp[arr[i].id]) {
            continue;
        }
        else {
          
            if (arr[i].x > minn) {
                for (int j = arr[i].id; j < r; j++) {
                    dp[j] = ans;
                    minn = min(minn, brr[j]);
                }
            }
            else {
                ans = arr[i].x;
                minn = 1e18;
                for (int j = arr[i].id; j < r; j++) {
                    dp[j] = ans;
                    minn = min(minn, brr[j]);
                }
            }
            r = arr[i].id;
            
        }
    }
    for (int i = 1; i <= n; i++) {
        cout << dp[i] << " ";
    }
    
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值