We were afraid of making this problem statement too boring, so we decided to keep it short. A sequenceis called non-boring if its every connected subsequence contains a unique element, i.e. an element suchthat no other element of that subsequence has the same value.Given a sequence of integers, decide whether it is non-boring.InputThe first line of the input contains the number of test cases T. The descriptions of the test cases follow:Each test case starts with an integer n (1 ≤ n ≤ 200000) denoting the length of the sequence. Inthe next line the n elements of the sequence follow, separated with single spaces. The elements arenon-negative integers less than 109.OutputPrint the answers to the test cases in the order in which they appear in the input. For each test caseprint a single line containing the word ‘non-boring’ or ‘boring’.Sample Input451 2 3 4 551 1 1 1 151 2 3 2 151 1 2 1 1Sample Outputnon-boringboringnon-boringboring
题意:就是判断一串数字的任意子序列是否满足至少有一个元素在该序列中只出现一次;题好理解,就是写有点难。
题解:对于一组数在区间(l,r)中有一个数M只出现一次,则只需要判断(l,M-1)和(M+1,r)区间是否有这样的数就可以啦,如果找不到返回false。可以利用递归,首先将该数组中的数从其位置开始向左右遍历,找到其左右第一个与其位置相同的下标(可以利用map来查找)。
AC代码为:
#include <iostream>
#include <algorithm> #include <map> #include <cstdio> #include<cstring> using namespace std; int a[200010]; int l[200010], r[200010]; int n; bool f(int left, int right) { if (left >= right)return true;for (int i = 0; i <= (right - left) / 2; i++){ if (l[left + i]<left && r[left + i]>right)return f(left, left + i - 1) && f(left + i + 1, right);if (l[right - i]<left && r[right - i]>right)return f(left, right - i - 1) && f(right - i + 1, right);}return false; } int main() { int T;scanf("%d", &T);while (T--){ map<int, int> m;scanf("%d",&n);for (int i = 0; i<n; i++)scanf("%d", a+i);m.clear();for (int i=0; i<n; i++){ if (m.count(a[i]))l[i] = m[a[i]];elsel[i] = -2;m[a[i]] = i;}m.clear();for (int i = n - 1; i >= 0; i--){ if (m.count(a[i]))r[i] = m[a[i]];elser[i] = n;m[a[i]] = i;s}if (f(0,n-1))printf("non-boring\n");elseprintf("boring\n");}return 0; }