本题需要考虑去重和检查范围
解法一:
使用桶,但是O(n*m),很慢但好理解
#include<iostream>
using namespace std;
int a[1000001] = { 0 };
bool cnt[1000001] = { 0 };
int main()
{
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int n, k;
cin >> n >> k;
int ans = 0;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
for (int i = 0; i < n; i++)
{
for (int j = 1; j <= k; j++)
{
if (a[i + j] == a[i]&&cnt[a[i]]==false)
{
cnt[a[i]] = true;
ans ^= a[i];
}
}
}
cout << ans;
return 0;
}
解法二:
O(n),很快,但需要对下标玩的很溜
#include<iostream>
#include<algorithm>
//#include<queue>
//#include <stack>
#include<string.h>
//#include <stdlib.h>
//#include <cstdio>
//#include<vector>
//#include "time.h"
//#include<math.h>
//#include <iomanip>
using namespace std;
//typedef long long ll;
//ll a, b, p;
int ki[1000010];//记录下标
bool ka[1000010];//是否取过
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n, k, a;
cin >> n >> k;
int ans = 0;
for (int i = 1; i <= n; i++)
{
cin >> a;
//如果取过就下一个,可以去重
if (ka[a] == 1)continue;
//如果下标没被记录过,就把第一次出现的a对应的下标序号存到ki中记录下来,直到出现重复的a出现不continue了,进下一个if判断
if (ki[a] == 0)
{
ki[a] = i;
continue;
}
//在小于等于k范围内实际上是下标的对比,看现在的a对应的下标i和上一次出现的a对应的下标ki[a]距离之差
if (i - ki[a] <= k)
{
//取这个a
ka[a] = 1;
//计算答案
ans ^= a;
}
//把本次出现的a的下标更新
ki[a] = i;
}
cout << ans;
return 0;
}
两种解法对比:
当然还有其他更好的解法,本人小白一只,浅浅记录一把。