1. 程式人生 > >HDU-5968異或密碼

HDU-5968異或密碼

opened 測試 序列 ava string pri .cn turn 對數

超級傳送門

題目描述:

晨晨在紙上寫了一個長度為N的非負整數序列{ai}。對於這個序列的一個連續子序列{al,al+1,…,ar}晨晨可以求出其中所有數異或的結果 alxoral+1xor...xorar其 中xor表示位異或運算,對應C、C++、 Java等語言中的^運算。
小璐提出了M個詢問,每個詢問用一個整數 xi描述。
對於每個詢問,晨晨需要找到序列{ai}的所有連續子序列,求出每個子序列異或的結果,找到所有的結果中與 xi之差的絕對值最小的一個,並告訴小璐相應子序列的長度。
若有多個滿足條件的連續子序列,則告訴小璐這些子序列中最長的長度。

Input:

包含多組測試數據,第一行一個正整數T,表示數據組數。
每組數據共兩行。
第一行包含N+1個非負整數。其中第一個數為N,表示序列的長度;接下來N 個數,依次描述序列{ ai}中的每個數。
第二行包含M+1個整數。其中第一個數為M,表示詢問的個數;接下來M個數 xi,每個數對應題目描述中的一個詢問。
保證 1 <= N <= 100,1 <= M <= 100,ai <= 1024,|xi| <= 1024,數據組數 <= 100。

Output

對於每組數據輸出M + 1行。前M行對應晨晨M個詢問的回答,第M + 1行為空行。

異或前綴對數組buf中的數字連續求異或(即 ^ 運算符),則 i 到 j 區間的異或值為 sum[j] ^ sum[j-1](類似於前綴和數組)

根據這個求得本題

技術分享圖片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <map>
 6 #define INF 0x3f3f3f3f
 7 
 8
using namespace std; 9 typedef long long ll; 10 const int maxn = 105; 11 12 13 int main() 14 { 15 int T; 16 scanf("%d",&T); 17 while(T--) 18 { 19 int buf[maxn],sum[maxn]; 20 memset(buf, 0, sizeof(buf)); 21 memset(sum, 0, sizeof(sum)); 22 int n,m; 23
scanf("%d",&n); 24 for(int i = 1; i <= n; i++) 25 { 26 scanf("%d",&buf[i]); 27 } 28 for(int i = 1; i <= n; i++) 29 { 30 sum[i] = sum[i - 1]^buf[i]; 31 } 32 scanf("%d",&m); 33 for(int k = 0; k < m; k++) 34 { 35 int q,len = 0,mmin = INF; 36 scanf("%d",&q); 37 for(int i = 1; i <= n; i++) 38 { 39 for(int j = i; j<= n; j++) 40 { 41 int t = abs(q - (sum[j]^sum[i-1])); 42 if(mmin > t) 43 { 44 mmin = t; 45 len = j - i + 1; 46 } 47 else if(mmin == t) 48 { 49 len = max(len, j - i + 1); 50 } 51 } 52 } 53 printf("%d\n",len); 54 } 55 printf("\n"); 56 } 57 return 0; 58 }
View Code

HDU-5968異或密碼