Non-boring sequences UVA

来源:互联网 发布:js 换行符 编辑:程序博客网 时间:2024/05/16 09:30

题目传送门

题意:给你长度为n的一个序列,如果这个序列的任何一个连续子序列都有至少一个出现了一次的数字就说这个序列是一个不无聊的序列,反之就是一个无聊的序列。

思路:这个题就是求出来每一个数字所在位置离他左右最近的相同的数字,然后进行搜索就可以了,从两边开始向中间搜索。

PS:这个题目遇到一个奇怪的问题,这个做法的复杂度应该是O(nlogn),但是花了2000+ms,我就一直在找原因,然后最后发现原因竟然是用memset把数组的所有元素都赋值为-1的问题,把memset改成了循环时间就只剩400ms了。

#include <algorithm>#include <cmath>#include <cstdio>#include <cstring>#include <fstream>#include <iostream>#include <list>#include <map>#include <queue>#include <set>#include <sstream>#include <stack>#include <string>#include <vector>#define MAXN 200010#define MAXE 210#define INF 1000000010#define MOD 1000000007#define LL long long#define pi acos(-1.0)using namespace std;int arr[MAXN];int PRE[MAXN];int NEXT[MAXN];typedef pair<int, int> P;map<int, int> num;bool check(int l, int r) {  if (l >= r)    return true;  int left = l, right = r;  while (left <= right) {    if (NEXT[left] > r && PRE[left] < l) {      return check(l, left - 1) && check(left + 1, r);    }     if (NEXT[right] > r && PRE[right] < l) {      return check(l, right - 1) && check(right + 1, r);    }    left++;    right--;  }  return false;}int main() {  std::ios::sync_with_stdio(false);  int T;  cin >> T;  for (int kase = 1; kase <= T; ++kase) {    num.clear();    int n;    cin >> n;    for (int i = 0; i < n; ++i) {      cin >> arr[i];    }    for (int i = 0; i <= n; ++i) {      NEXT[i] = n + 1;      PRE[i] = -1;    }    for (int i = 0; i < n; ++i) {      if (num.count(arr[i])) {        PRE[i] = num[arr[i]];        NEXT[num[arr[i]]] = i;        num[arr[i]] = i;      } else {        num[arr[i]] = i;      }    }    if (check(0, n - 1))      cout << "non-boring\n";    else      cout << "boring\n";  }  return 0;}/*451 2 3 4 551 1 1 1 151 2 3 2 151 1 2 1 1*/