nyoj 133 子序列(尺取法+离散化)
生活随笔
收集整理的這篇文章主要介紹了
nyoj 133 子序列(尺取法+离散化)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
子序列
時間限制:3000?ms ?|? 內存限制:65535?KB 難度:5 描述給定一個序列,請你求出該序列的一個連續的子序列,使原串中出現的所有元素皆在該子序列中出現過至少1次。
如2 8 8 8 1 1,所求子串就是2 8 8 8 1。
輸入每組測試數據的第一行是一個整數N(1<=N<=1000000),表示給定序列的長度。
隨后的一行有N個正整數,表示給定的序列中的所有元素。
數據保證輸入的整數都不會超出32位整數的范圍。
解題思路:這道題數據比較大,可以先用離散化。接下來就是經典的尺取法了。。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<set> #include<map> using namespace std;const int maxn = 1000005; const int inf = 0x3f3f3f3f; int n,cnt,a[maxn],tmp[maxn]; int idx[maxn],Count[maxn];int bisearch(int l,int r,int key) {int mid;while(l <= r){mid = (l + r) >> 1;if(tmp[mid] == key) return mid;else if(tmp[mid] < key) l = mid + 1;else r = mid - 1;} }void Discrete() {sort(tmp+1,tmp+1+n);cnt = 0;tmp[++cnt] = tmp[1];for(int i = 2; i <= n; i++)if(tmp[i] != tmp[i-1])tmp[++cnt] = tmp[i];for(int i = 1; i <= n; i++)idx[i] = bisearch(1,cnt,a[i]); }int main() {int t;scanf("%d",&t);while(t--){scanf("%d",&n);for(int i = 1; i <= n; i++){scanf("%d",&a[i]);tmp[i] = a[i];}Discrete();memset(Count,0,sizeof(Count));int r = 1,sum = 0,ans = inf;for(int i = 1; i <= n; i++){if(Count[idx[i]] == 0) sum++;Count[idx[i]]++;while(sum == cnt){Count[idx[r]]--;if(Count[idx[r]] == 0) sum--;ans = min(ans,i - r + 1);r++;}}printf("%d\n",ans);}return 0; }總結
以上是生活随笔為你收集整理的nyoj 133 子序列(尺取法+离散化)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信开放平台公众号第三方平台开发 教程一
- 下一篇: 【技术文档】jeecg3.7-maven