题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5968
思路:先把所有的连续异或值保存起来,排序,然后用二分找到距离x最近的那个点,判断即可;
#include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> #include <bitset> #include <iostream> #include <time.h> typedef long long LL; using namespace std; const int N = 105; const double eps = 1e-10; const int INF = 0x3f3f3f3f; const int mod = 1000000007; struct node { int len, num; }c[N*N]; int a[N], b[N], k, c1[N*N], c2[N*N]; bool cmp(node p, node q) { if(p.num!=q.num) return p.num<q.num; return p.len < q.len; } int Find(int num) { int pos = upper_bound(c1, c1+k, num)-c1; return c2[pos-1]; } int solve(int x)///Find x in the c[]; { int pos = lower_bound(c1, c1+k, x)-c1; if(pos == 0 || c1[pos] == x)///如果数组中含有x,那就找到异或值为x的最大长度; return Find(c1[pos]); int p = abs(c1[pos]-x); int q = abs(c1[pos-1]-x); int ans1 = Find(c1[pos]); int ans2 = Find(c1[pos-1]); if(p < q || (p == q && ans1>ans2)) return ans1; return ans2; } int main() { int T, n, m; scanf("%d", &T); while(T --) { scanf("%d", &n); memset(a, 0, sizeof(a)); memset(b, 0, sizeof(b)); memset(c, 0, sizeof(c)); for(int i=1; i<=n; i++) { scanf("%d", &a[i]); b[i] = b[i-1]^a[i]; } k = 0; for(int i=1; i<=n; i++)/// the length is i; { for(int j=1; i+j-1<=n; j++)/// from j to j+i; { int num = b[j+i-1]^b[j-1]; c[k].len = i; c[k++].num = num; } } sort(c, c+k, cmp); for(int i=0; i<k; i++) { c1[i] = c[i].num; c2[i] = c[i].len; } scanf("%d", &m); for(int i=1; i<=m; i++) { int x; scanf("%d", &x); int ans = solve(x); printf("%d ", ans); } printf(" "); } return 0; }