Codeforces codefest19 08-25

社论(题解)

** 题解链接 **


A题

** 题目链接 **

题意及思路

  • 题意:给出a,b,n,求n的按位异或值。如果n=0,则ans=a,如果n=1,ans=b。否则ans = f(n-1)^f(n-2)。
  • 思路:n=2时,ans = a^b;n=3时,ans = a^b^b = a;n=4时,ans = a^b ^a = b;意即,异或形式为三个一组。对n%3即可得出答案。见代码描述。

代码

#include<bits/stdc++.h>

using namespace std;

int main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    int t,a,b,n,ans;
    cin >> t;
    while(t--){
        cin >> a >> b >> n;
        if(n%3==0) ans = a;
        else if(n%3==1) ans = b;
        else ans = a^b;
        cout << ans << endl;
    }

    return 0;
}

B题

** 题目链接 **

题意及思路

  • 题意:给定的数组中,可能含有重复的元素。要求我们以删除最少的子段长度为代价,进行数组去重操作。例如 2 1 2 1中,我们删除下标1和下标2上的元素,剩余的数组元素为2 1。
  • 思路:在删除一段子段后,数组前缀和后缀将会被保留,可能长度为0。我们需要找到的是一个不包含任何重复元素的前缀下标最大值 和 一个不包含任何重复元素的后缀下标最小值(这样下标差才能最小,当然这也就是找到最长前缀和最长后缀)。我们可以使用map/set来跟踪元素。

代码

#include<bits/stdc++.h>

using namespace std;

const int N = 2005;
int a[N];

int main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    for(int i=0;i<n;i++) cin >> a[i];

    int ans = n-1;
    map<int,int> frq;
    for(int i=0;i<n;i++){
        bool validPrefix = true;
        for(int j=0;j<i;j++){
            frq[a[j]]++;
            if(frq[a[j]]==2){
                validPrefix = false;
                break;
            }
        }
        int min_index_suffix = n;
        for(int j=n-1;j>=i;j--){
            frq[a[j]]++;
            if(frq[a[j]]==1){
                min_index_suffix = j;
            }else break;
        }
        if(validPrefix){
            ans = min(ans,min_index_suffix-i);
        }
        frq.clear();
    }
    cout << ans << "\n";

    return 0;
}

C题

** 题目链接 **

题意及思路

  • 题意:
  • 思路:

代码

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务