社论(题解)
** 题解链接 **
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题
** 题目链接 **
题意及思路
- 题意:
- 思路: