Codeforces 558B Amr and The Large Array 数组美丽值

题意:给一个数组,记数组中出现次数最多的元素出现的次数为这个数组的美丽值,求这个数组长度最短的子数组(要连续),使得该子数组的美丽值与原数组美丽值相等。要求输出子数组的起始和结束位置下标(从1开始)。






也是个水题。每个数最大才10^6,用hash存储每个数出现的次数即可。注意有可能有多个不同的元素出现的次数都相等且为最大,需要一一判断。遍历数组的时候可以用两个值 l[i],r[i] 维护每个数最左出现的位置和最右出现的位置。这样可以直接计算长度。









#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

const int MAX = 1000005;
const int INF = 100005;
int n, a[INF], cnt[MAX], start[MAX], finish[MAX], number; //start起始下标,finish结束下标,number美丽值

void input()
{
    memset(cnt, 0, sizeof(cnt));
    for(int i = 0; i < MAX; i++)
    {
        start[i] = INF;
        finish[i] = 0;
    }
    number = 0;
    for(int i = 0; i < n; i++)
    {
        scanf("%d", &a[i]);
        cnt[a[i]]++;
        start[a[i]] = min(start[a[i]], i + 1); //维护起始下标
        finish[a[i]] = max(finish[a[i]], i + 1); //维护结束下标
        number = max(number, cnt[a[i]]);
    }
}

void solve()
{
    int l = 0, r = n;
    for(int i = 0; i < n; i++)
    {
        if(cnt[a[i]] == number)
        {
            if(finish[a[i]] - start[a[i]] < r - l) //长度更短
            {
                l = start[a[i]];
                r = finish[a[i]];
            }
        }
    }
    printf("%d %d\n", l, r);
}

int main()
{
    while(scanf("%d", &n) != EOF)
    {
        input();
        solve();
    }
    return 0;
}

你可能感兴趣的:(水题)