题意:给一个数组,记数组中出现次数最多的元素出现的次数为这个数组的美丽值,求这个数组长度最短的子数组(要连续),使得该子数组的美丽值与原数组美丽值相等。要求输出子数组的起始和结束位置下标(从1开始)。
也是个水题。每个数最大才10^6,用hash存储每个数出现的次数即可。注意有可能有多个不同的元素出现的次数都相等且为最大,需要一一判断。遍历数组的时候可以用两个值 l[i],r[i] 维护每个数最左出现的位置和最右出现的位置。这样可以直接计算长度。
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <string> #include <stack> #include <queue> #include <vector> #include <map> 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; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-09-28 20:11:20