1. 程式人生 > >UVa 11572 - Unique Snowflakes

UVa 11572 - Unique Snowflakes

online style 情況 ont print ans int item std

鏈接:

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2619

題意:

輸入一個長度為n(n≤1e6)的序列A,找到一個盡量長的連續子序列A[L]~A[R],使得該序列中沒有相同的元素。

分析:

滑動窗口法。
假設序列元素從0開始編號,所求連續子序列的左端點為L,右端點為R。
首先考慮起點L=0的情況。可以從R=0開始不斷增加R,相當於把所求序列的右端點往右延伸。
當無法延伸(即A[R+1]在子序列A[L~R]中出現過)時,只需增大L,並且繼續延伸R。


既然當前的A[L~R]是可行解,L增大之後必然還是可行解,所以不必減少R,繼續增大即可。
可以這樣判斷R是否可以延伸:
用一個map求出 last[i],即下標i的“上一個相同元素的下標”。
例如,輸入序列為3 2 4 1 3 2 3,當前區間是[1,3](即元素2, 4, 1),是否可以延伸呢?
下一個數是A[4]=3,它的“上一個相同位置”是下標0(A[0]=3),不在區間中,因此可以延伸。

代碼:

 1 #include <cstdio>
 2 #include <map>
 3 using namespace std;
 4 
 5 int main(){
 6     int
T; 7 scanf("%d", &T); 8 while(T--){ 9 int n, ans = 0; 10 scanf("%d", &n); 11 map<int,int> last; 12 for(int i, L = 0, R = 1; R <= n; R++){ 13 scanf("%d", &i); 14 if(last[i] > L) L = last[i]; 15 if(ans < R - L) ans = R - L;
16 last[i] = R; 17 } 18 printf("%d\n", ans); 19 } 20 return 0; 21 }

UVa 11572 - Unique Snowflakes