【題目】
B. Lost Array
【描述】
Bajtek有一個數組x[0],x[1],...,x[k-1]但被搞丟了,但他知道另一個n+1長的數組a,有a[0]=0,對i=1,2,...,n。由此可以找到數組x[0],x[1],...,x[k-1]的一些可能情況,即滿足這個關系的數組x[0],x[1],...,x[k-1]。問一共有多少種可能的數組x[0],x[1],...,x[k-1]的長度k,輸出可能的數量以及所有可能的長度k。
數據范圍:1<=n<=1000,1<=a[i]<=10^6(這里不包括a[0],默認a[0]=0)
【思路】
?先不考慮數組x是循環的,即不考慮數組x是有限長的,那么由數組a可以反解出與數組a等長的一個數組“x”,我們要找的真正的數組x實際上是這個反解出來的“x”的一個周期,我們要找的就是這個“x”有多少種周期長度。
要驗證i是不是“x”的一個周期長度,則將“x”的元素分為i組,即下標模i相同的分到一組,檢查每一組從前往后數第某個元素是不是都是相同的。這里復雜度是O(n)的。
對i進行枚舉,即可找到所有可能的周期長度。至此復雜度為O(n^2)。
【我的實現】
?復雜度:O(n^2)


1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 6 using namespace std; 7 #define MaxN 1020 8 int x[MaxN]; 9 int Ans[MaxN]; 10 11 int main() 12 { 13 int n; 14 int a, pre_a = 0; 15 int i, j, k; 16 //int cur; 17 bool flag; 18 scanf("%d", &n); 19 for(i = 1; i <= n; i++) 20 { 21 scanf("%d", &a); 22 x[i-1] = a - pre_a; 23 pre_a = a; 24 } 25 for(i = 1; i <= n; i++) //step = i 26 { 27 flag = false; 28 for(j = 0; j < i; j++) //start at j for each zhouqi 29 { 30 for(k = j; k < n; k += i) 31 { 32 if(k > j && x[k] != x[k-i]) 33 { 34 flag = true; 35 break; 36 } 37 } 38 if(flag) 39 break; 40 } 41 if(!flag) 42 Ans[++Ans[0]] = i; 43 } 44 printf("%d\n", Ans[0]); 45 for(i = 1; i <= Ans[0]; i++) 46 printf("%d ", Ans[i]); 47 return 0; 48 }
【評測結果】
?