1 条题解

  • 0
    @ 2025-11-18 11:57:40
    • 考虑 同向双指针
    • rr 向右扩展时,如果新来的数出现次数为 11,那就是新来了一个不同的数
    • ll 向右扩展时,需要删除 a[l]a[l],如果 a[l]a[l] 出现的次数为 11,说明 a[l+1]a[r]a[l + 1] \sim a[r] 中没有 a[l]a[l]
    #include <bits/stdc++.h>
    using namespace std;
    
    void solve(vector<int>& a, int m) {
        int n = a.size(), x = 0, y = n - 1;
    
        vector<int> cnt(m + 1, 0);  // cnt(i): i 出现的次数
    	int tol = 0;                // 当前不同数的数个数
    
        for (int l = 0, r = -1; l < n; l++) {
    		// 当前还没有 m 个不同的数, 就往右扩展 r
    		while (tol < m && r + 1 < n) {
    			// a[r + 1] 出现的次数为 1, 说明是新来的数
    			if (++cnt[a[++r]] == 1) tol++;
    		}
    		if (tol == m && r - l < y - x) x = l, y = r;
    
    		// 把 a[l] 删除, 准备计算 a[l + 1]
    		// a[l] 出现的次数为 0, 说明 tol 得变小
    		if (--cnt[a[l]] == 0) tol--;
        }
        cout << x + 1 << ' ' << y + 1 << '\n';
    }
    
    int main() {	
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
    
        int n, m;
        cin >> n >> m;
        vector<int> a(n);
        for (int i = 0; i < n; i++) cin >> a[i];
        solve(a, m);
    
    	return 0;
    }
    
    • 1

    【普及】包含所有数的最短区间

    信息

    ID
    180
    时间
    1000ms
    内存
    128MiB
    难度
    5
    标签
    递交数
    77
    已通过
    30
    上传者