美文网首页
笔试刷题-头条2018-07-04

笔试刷题-头条2018-07-04

作者: Dodo159753 | 来源:发表于2018-07-04 08:06 被阅读0次

题目描述:

/**
给定整数m以及n各数字A1,A2,..An,
将数列A中所有元素两两异或,共能得到n(n-1)/2个结果,
请求出这些结果中大于m的有多少个。
输入描述:
第一行包含两个整数n,m.
第二行给出n个整数A1,A2,...,An。
数据范围
对于30%的数据,1 <= n, m <= 1000
对于100%的数据,1 <= n, m, Ai <= 10^5
输出描述:
输出仅包括一行,即所求的答案
输入例子1:
3 10
6 5 10
输出例子1:
2
*/

思路如下:

建立数据的Trie树,并根据m进行剪枝即可
为了能剪枝,要在建立的时候再节点加入该节点下有多少个数的信息即可
这里的数字范围最多10^5, 所以17位就可以了
这里的插入全是17位的数据都是等长的

代码如下:

#include<stdio.h>
#include<iostream>
#include<vector>
#include<map>
 
#define MAX 100000
#define MAX_N 100000
#define MAX_DIGIT_NUM 17
//#define MAX_DIGIT_NUM 4
#define MAX_CHILDREN_NUM 2
 
typedef long long LL;
 
using namespace std;
 
struct TrieNode
{
    int numOfLeaves=0;
    TrieNode *children[MAX_CHILDREN_NUM];
    TrieNode()
    {
        for(int i=0; i<MAX_CHILDREN_NUM; i++)
            this->children[i]=NULL;
    }
};
 
class Dict
{
public:
    Dict() {}
 
    void add(int num)
    {
        int mask=1<<(MAX_DIGIT_NUM-1);
        TrieNode *curNode=this->root;
        for(int digitNum=MAX_DIGIT_NUM-1; digitNum>=0; digitNum--)
        {
            int curDigitOfNum=mask#
            curDigitOfNum=curDigitOfNum>>digitNum;
            TrieNode **children=curNode->children;
            if(children[curDigitOfNum]==NULL)
            {
                children[curDigitOfNum]=new TrieNode();
            }
            children[curDigitOfNum]->numOfLeaves++;
            //往下走
            curNode=children[curDigitOfNum];
            //掩码更新
            mask=mask>>1;
        }
    }
 
    int findQualifiedLeaves(int num, int target)
    {
        int accQualifiedLeaves=0;
        int mask=1<<(MAX_DIGIT_NUM-1);
        TrieNode *curNode=this->root;
        for(int digitNum=MAX_DIGIT_NUM-1; digitNum>=0; digitNum--)
        {
            if(curNode==NULL)
                break;
            int curDigitOfNum=mask#
            curDigitOfNum=curDigitOfNum>>digitNum;
            int curDigitOfTarget=mask⌖
            curDigitOfTarget=curDigitOfTarget>>digitNum;
            TrieNode **children=curNode->children;
            if(curDigitOfTarget==1){
                //此时不可能组合出比目标大的
                if(children[curDigitOfNum^1]==NULL){
                    break;
                    //return accQualifiedLeaves;
                }
                //还有可能组合出比目标大的,但只能走当前位的相反的位
                curNode=children[curDigitOfNum^1];
            }
            else if(curDigitOfTarget==0){
                //此时直接存在一个孩子的子树组合出比目标大的
                if(children[curDigitOfNum^1]!=NULL){
                    accQualifiedLeaves+=children[curDigitOfNum^1]->numOfLeaves;
                }
                //只需要往下走到跟当前位置相同的节点即可
                curNode=children[curDigitOfNum];
            }
            //掩码更新
            mask=mask>>1;
        }
        return accQualifiedLeaves;
    }
 
private:
    TrieNode *root=new TrieNode();
};
 
int nums[MAX_N];
 
int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    //建立字典
    Dict *dict=new Dict();
    for(int i=0; i<n; i++){
        int num;
        scanf("%d", &num);
        if(num<1 || num>MAX)
            return -1;
        nums[i]=num;
        dict->add(num);
    }
    //计算总的对数包含了顺序
    LL totalPairs=0;
    for(int i=0; i<n; i++)
    {
        totalPairs+=(LL)dict->findQualifiedLeaves(nums[i], m);
    }
    printf("%lld", totalPairs/2);
    return 0;
}

相关文章

  • 笔试刷题-头条2018-07-04

    题目描述: 思路如下: 建立数据的Trie树,并根据m进行剪枝即可为了能剪枝,要在建立的时候再节点加入该节点下有多...

  • 笔试刷题-头条2018-06-01

    题目描述: 思路如下:把用户按照k值排序,然后用两次二分查找找出了每次查询所有符合条件的其k值与查询相同的用户,然...

  • 笔试刷题-头条2018-05-31

    题目描述 思路如下:采用的是bfs的思想,从root开始,然后依次放入其lch rch分别处理指针,由于要标记什么...

  • 笔试刷题-头条2018-05-31

    思路如下:由于只有两个字符,就找其中一个字符来变,另一个也变,看最后可以组成的最长字符串 维护两个列表去记录两个字...

  • 笔试刷题-头条2018-06-02

    题目介绍: 思路简介:colorPosTable[c]表示第c种颜色出现的位置(按照顺时针录入) colorSet...

  • 笔试刷题-头条2018-07-08

    题目描述: 思路如下: 设dp[i]为到达i门,并且进入次数为偶数时需要移动的次数 一开始为0 第二次进入1要两次...

  • 笔试刷题-头条2018-07-10

    题目描述: 思路如下: 类似柱状图扩展长方形求最大面积即可用栈更新一个点可以向左扩展到哪里,向右可以扩展到哪里然后...

  • 笔试刷题-头条2018-07-03

    题目描述: 思路如下: 把难度从小到大排序,然后用一个标记题目是否用于考试然后对于三个连续的题目按遍历顺序mark...

  • 笔试刷题-头条2018-07-07

    题目描述: 思路如下: 1.最后一个分配的房间里的人数就是最小值,这种情况这个房间里的人就是先前被请出去了,也就是...

  • 笔试刷题-头条2018-07-06

    题目描述: 思路如下: 维护一个表每个每行存放同样字符之间的位置(按原来顺序摆放)在位置向量中dp[i][j] =...

网友评论

      本文标题:笔试刷题-头条2018-07-04

      本文链接:https://www.haomeiwen.com/subject/mzvsuftx.html