zoukankan      html  css  js  c++  java
  • B. Uniqueness(尺取)

    B. Uniqueness
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    You are given an array a1,a2,,ana1,a2,…,an. You can remove at most one subsegment from it. The remaining elements should be pairwise distinct.

    In other words, at most one time you can choose two integers ll and rr (1lrn1≤l≤r≤n) and delete integers al,al+1,,aral,al+1,…,ar from the array. Remaining elements should be pairwise distinct.

    Find the minimum size of the subsegment you need to remove to make all remaining elements distinct.

    Input

    The first line of the input contains a single integer nn (1n20001≤n≤2000) — the number of elements in the given array.

    The next line contains nn spaced integers a1,a2,,ana1,a2,…,an (1ai1091≤ai≤109) — the elements of the array.

    Output

    Print a single integer — the minimum size of the subsegment you need to remove to make all elements of the array pairwise distinct. If no subsegment needs to be removed, print 00.

    Examples
    input
    Copy
    3
    1 2 3
    
    output
    Copy
    0
    
    input
    Copy
    4
    1 1 2 2
    
    output
    Copy
    2
    
    input
    Copy
    5
    1 4 1 4 9
    
    output
    Copy
    2
    
    Note

    In the first example all the elements are already distinct, therefore no subsegment needs to be removed.

    In the second example you can remove the subsegment from index 22 to 33.

    In the third example you can remove the subsegments from index 11 to 22, or from index 22 to 33, or from index 33 to 44.

    题目链接:http://codeforces.com/contest/1208/problem/B

    题解:建立一个map,来记录某个值出现的次数。先从后往前遍历,找到第一个重复的值,记录该位置。然后,从前后遍历,如果当前的这个值在后面出现过,我就需要找到后米娜那个值出现的位置,然后记录最小值,重复操作n次。还是看代码理解把。。。

    #include <iostream>
    #include <cstdio>
    #include <map>
    
    using namespace std;
    
    const int maxn = 2e3+7;
    
    map<int, int> mp;
    int arr[maxn];
    
    int main() {
        int n;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            scanf("%d", &arr[i]);
        }
        int j = n;
        while(j >= 1) {        //找到第一个重复的值的位置
            if(mp[arr[j]] >= 1) {
                break;
            }
            mp[arr[j]]++;
            j--;
        }
        int ans = INT_MAX;
        for(int i = 1; i <= n; i++) {
            ans = min(ans, j - i + 1);
            mp[arr[i]]++;
            while(mp[arr[i]] >= 2 && j <= n) {    //找到后面这段中已经匹配过,且与当前值相同数的位置
                j++;
                mp[arr[j]]--;
            }
            if(mp[arr[i]] >= 2) {    //如果前面的操作都做完了,还有相同的值,就需要跳出,可以看下面这组样例来模拟
                                    //6
                                    //9 6 4 4 9 4
                break;
            }
        }
        printf("%d
    ", ans);
        return 0;
    }
  • 相关阅读:
    POJ 1001 Exponentiation
    POJ 2105 IP Address
    条款1:视C++为一个语言联邦
    条款2:尽量使用const ,enum,inline替换define
    走台阶问题
    Oracle之分页问题
    Oracle之子查询:Top-N问题
    Facade——外观模式
    PROXY——代理模式
    C++ 内联函数
  • 原文地址:https://www.cnblogs.com/buhuiflydepig/p/11411498.html
Copyright © 2011-2022 走看看