• 异或密码---hdu5968(CCPC合肥,二分)


     题目链接: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;
    }
    View Code
  • 相关阅读:
    两个有序链表的合并
    Perl学习笔记
    生信-基本概念
    生信-序列比较dp[未完成]
    PAT 1091 Acute Stroke [难][bfs]
    PAT 1038 Recover the Smallest Number[dp][难]
    PAT 1078 Hashing[一般][二次探查法]
    PAT 1122 Hamiltonian Cycle[比较一般]
    PAT 1151 LCA in a Binary Tree[难][二叉树]
    PAT 1148 Werewolf
  • 原文地址:https://www.cnblogs.com/zhengguiping--9876/p/6033267.html
Copyright © 2020-2023  润新知