Codeforces1157E. Minimum Array

题目http://codeforces.com/contest/1157/problem/E

题意:给定整数型n,a与b数组长度均为n,其中的a与b中的每个元素大小为0<= a[i] (或者b[i]) <n,现在可以改变b数组的元素顺序,用现在的b数组与a数组做如下操作:

          c[i] = ( a[i] + b[i] ) % n

          最后操作完之后的c数组要保证字典序最小。输出这样的c数组

 

思路:因为是模操作并且元素的数据范围容易让我们想到这里面的模操作会形成闭环。比如n=5,当前a=2,那么b=0,1,2,3,4对应的结果为2,3,4,0,1形成了闭环。并且这样的环不会重叠,毕竟a与b的数据范围在这里放着。这里n-a=3是最优的答案,那么如果找不到这样的刚刚好的答案怎么选择? 

          lower_bound(n-a)找到是距离现在n-a最近的点,但是会有一个疑问在n-a有左右两种选择,我们究竟是向左选择还是向右选择?显然lower_bound(n-a)是向右贪心选择的,怎么才能排除左边的点呢?

         这里有两种情况,如果b数组中没有一个数大于等于n-a,那么是不是理解为此时的lower_bound找到的是end()?此时最优的就是左数第一个元素最优咯。第二种情况,lower_bound能够找到,设当前找到的元素为find,那么我们就是比较(find+a)%n与(a+b[0])%n的大小,因为find+a>n但是一定是小于2n的,所以(find+a)%n = find+a-n,发现什么了吗?find+a-n<a<=a+b[0],所以此时的向右找到的第一个值一定是对的。

 

AC code

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

int n;
int a[maxn],b[maxn];
multiset<int>res;

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&b[i]);
        res.insert(b[i]);
    }

    for(int i=1;i<=n;i++)
    {
        int tmp=n-a[i];
        auto findd=res.lower_bound(tmp);
        if(findd==res.end())
            findd=res.begin();
        int ans=*findd;
        res.erase(findd);
        printf("%d%c",(ans+a[i])%n,i==n?'\n':' ');
    }
    return 0;
}

 

### Codeforces 887E Problem Solution and Discussion The problem **887E - The Great Game** on Codeforces involves a strategic game between two players who take turns to perform operations under specific rules. To tackle this challenge effectively, understanding both dynamic programming (DP) techniques and bitwise manipulation is crucial. #### Dynamic Programming Approach One effective method to approach this problem utilizes DP with memoization. By defining `dp[i][j]` as the optimal result when starting from state `(i,j)` where `i` represents current position and `j` indicates some status flag related to previous moves: ```cpp #include <bits/stdc++.h> using namespace std; const int MAXN = ...; // Define based on constraints int dp[MAXN][2]; // Function to calculate minimum steps using top-down DP int minSteps(int pos, bool prevMoveType) { if (pos >= N) return 0; if (dp[pos][prevMoveType] != -1) return dp[pos][prevMoveType]; int res = INT_MAX; // Try all possible next positions and update 'res' for (...) { /* Logic here */ } dp[pos][prevMoveType] = res; return res; } ``` This code snippet outlines how one might structure a solution involving recursive calls combined with caching results through an array named `dp`. #### Bitwise Operations Insight Another critical aspect lies within efficiently handling large integers via bitwise operators instead of arithmetic ones whenever applicable. This optimization can significantly reduce computation time especially given tight limits often found in competitive coding challenges like those hosted by platforms such as Codeforces[^1]. For detailed discussions about similar problems or more insights into solving strategies specifically tailored towards contest preparation, visiting forums dedicated to algorithmic contests would be beneficial. Websites associated directly with Codeforces offer rich resources including editorials written after each round which provide comprehensive explanations alongside alternative approaches taken by successful contestants during live events. --related questions-- 1. What are common pitfalls encountered while implementing dynamic programming solutions? 2. How does bit manipulation improve performance in algorithms dealing with integer values? 3. Can you recommend any online communities focused on discussing competitive programming tactics? 4. Are there particular patterns that frequently appear across different levels of difficulty within Codeforces contests?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值