--- title: "品种临近" created: 2025-11-28 tags: - 算法 --- # 品种临近 ## 题目 [品种临近](https://www.acwing.com/problem/content/description/1971/) ![[image-317b8fcc.png]] ## 思路分析 可以从两个方向考虑 在一个区间内 某个数如果出现两次 就说明它可能是答案 放入max维护 这是通过不断维护一个滑动窗口做到的 维护滑动窗口可以用双指针做 也可以用队列来做 甚至还可以直接从r入手 对于每一个r找到记录的他左边的那个l的位置 如果距离小于k 就可能是答案 放入max维护 ## 代码实现 **双指针(值做下标计数)44ms** ```cpp #include using namespace std; #define endl '\n' const int N=50010,M=1e6+10; int cows[N],cnt[M]; int n,k; int main() { ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); cin>>n>>k; for(int i=0;i>cows[i]; int res=-1; for(int right=0,left=0;rightk){ cnt[cows[left]]--; left++; } if(cnt[cows[right]]>=2) res=max(res,cows[right]); } cout< using namespace std; #define endl '\n' const int N=50010; int cows[N]; map cnt; int n,k; int main() { ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); cin>>n>>k; for(int i=0;i>cows[i]; int res=-1; for(int right=0,left=0;rightk){ cnt[cows[left]]--; left++; } if(cnt[cows[right]]>=2) res=max(res,cows[right]); } cout< using namespace std; #define endl '\n' const int N=50010,M=1e6+10; queue cows; int cnt[M]; int n,k; int main() { ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); cin>>n>>k; int res=-1; for(int i=0;i>id; if(cnt[id]>0)//加入后会>=2是答案 意味着加入之前是1即为候选答案 res=max(res,id); cows.push(id); cnt[id]++; if(cows.size()>k){ cnt[cows.front()]--; cows.pop(); } } cout< using namespace std; #define endl '\n' const int N=50010,M=1e6+10; int last_pos[M]; int n,k,res=-1; int main() { ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); cin>>n>>k; for(int i=1;i<=n;i++){ int x;cin>>x; if(last_pos[x] && i-last_pos[x]<=k) res=max(res,x); last_pos[x]=i; } cout<