zoukankan      html  css  js  c++  java
  • 一些比赛的题目

    题意:

    给定的三个由'0','1','2','3','?'构成的字符串A,B,C。其中'?'表示该位可能是0,1,2,3,现在如果有三个四进制的数依次是这三个字符串,若有A+B=C,则称[A,B,C]是这三个字符串的一组解,现在给定A,B,C,求解的个数。

    题解 1:

    搜索:一开始觉的就是用搜索的办法枚举 a和b的所有情况然后和c比较;这个想法是对的,但怎么实现呢,一开是以为将 a,b分别放到两个数组里 分别搜索,但是 怎么搜啊,两个数组

    后来想到 ,将a和b 存到一个数组里面,前六位存a 从第七为开始 存b (首先要使a,b倒置,再存),然后搜索就可以了;

    View Code
    #include<stdio.h>
    #include<string.h>
    #define inf 9999999
    #define maxn 10
    int ans;
    char a[maxn*2],b[maxn],c[maxn];
    int na[maxn*2],nb[maxn],nc[maxn],num[maxn*2];
    void DFS(int x)
    {
        int i;
        if(x>=12)
        {
            for(i=0;i<7;i++)num[i]=0;
            for(i=0;i<6;i++)
            {
                num[i]+=na[i]+na[i+6];
                num[i+1]+=num[i]/4;
                num[i]=num[i]%4;
    
            }
            for(i=0;i<7;i++)
            {
    
                if(nc[i]!=num[i]&&nc[i]!=-1)
                {
                    return ;
                }
            }
    
            ans++;
    
            return ;
        }
        if(na[x]==-1)
        {
            for(i=0;i<4;i++)
            {
                na[x]=i;
                DFS(x+1);
    
            }na[x]=-1;
    
        }
        else DFS(x+1);
    }
    int main()
    {
        int i;
        while(scanf("%s%s%s",a,b,c)!=EOF)
        {
    
    
        memset(na,0,sizeof(na));
        memset(num,0,sizeof(num));
        memset(na,0,sizeof(na));
        memset(nb,0,sizeof(nb));
        memset(nc,0,sizeof(nc));
        int len=strlen(a);
        for(i=0;i<len;i++)
        {
            if(a[len-1-i]!='?')
            na[i]=a[len-1-i]-'0';
            else  na[i]=-1;
    
        }
        len=strlen(b);
        for(i=0;i<len;i++)
        {
            if(b[len-1-i]!='?')
            na[i+6]=b[len-1-i]-'0';
            else na[i+6]=-1;
        }
        len=strlen(c);
        for(i=0;i<strlen(c);i++)
        {
            if(c[len-1-i]!='?')
            nc[i]=c[len-1-i]-'0';
            else nc[i]=-1;
        }
    
        ans=0;
        DFS(0);
        printf("%d\n",ans);
        }
    
    }

    题解2:

     运用dp

      因为到达以为时无非有两种情况, 有进位,没进位

      dp[i][0]表示前i位,第i位没有进位时,有多少中

      dp[i][1]表示前i位,第i位有进位时,有多少种

    View Code
    1002:题意 想必大家已经知道如何建立二叉排序树了吧.二叉排序树的介绍如链接所示 http://baike.baidu.com/view/922220.htm
    例如依次给出9个正整数:8 ,3, 10, 1, 6, 14 ,4 ,7 ,13,建立后的二叉排序树如下图所示.


    现在依次给出N个不同的正整数,每个数都不大于10^9,利用这N个有顺序的正整数可以建立出一颗二叉排序树.对于建成的这颗二叉排序树,询问某个节点的祖父节点的值(若该节点没有祖父节点则输出-1).
    一般的二叉排序树建图的话,会超时,这里用的了另一种高级的数据结构 笛卡尔树 ,迪卡而数和treap 基本上一样支部过时,他的alue值是预先设定好的,
    介绍“:
    笛卡尔树又称笛卡儿树,在数据结构中属于二叉树的一种。   笛卡尔树结构由Vuillmin在解决范围搜索的几何数据结构问题时提出的,从数列中构造一棵 笛卡尔树可以线性时间完成,需要采用基于栈的算法来找到在该数列中的所有最近小数。由此可知,笛卡尔树是一种特定的二叉树数据结构,可由数列构造,在范围 最值查询、范围top k查询(range top k queries)等问题上有广泛应用。它具有堆的有序性,中序遍历可以输出原数列。   可以这么说:笛卡尔树是一棵二叉树,树的每个节点有两个值,一个为key,一个为value。 光看key的话,笛卡尔树是一棵二叉搜索树,每个节点的左子树的key都比它小,右子树都比它大;光看value的话,笛卡尔树有点类似堆,根节点的 value是最小(或者最大)的,每个节点的value都比它的子树要大
    题解:
    View Code
    #include <iostream>
    #include<stdio.h>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <set>
    #include <ctime>
    #include <queue>
    #include <map>
    #include <sstream>
    #include<stdlib.h>
    #include<stdio.h>
    #define CL(a,num)  memset(a,num,sizeof(a))
    #define  MIN(a,b)  a>b?b:a
    #define MAX(a,b)   a>b?a:b
    #define maxn 50010
    using namespace std;
    map<int ,int >map1;
    int n,m;
    struct node
    {
        int k,val;
        int lc,rc,pre;
    }p[maxn];
    int cmp( const void *a ,const void *b)
    {
    return (*(node *)a).k > (*(node *)b).k ? 1 : -1;
    }
    void build_tree()
    {
        int i,k;
        p[0].rc=1;
        k=1;
        for(i=2;i<=n;i++)
        {
            while(p[k].val>p[i].val)k=p[k].pre;//每一次找到第一个比他val小的,因为先排序处理了,所以肯定是沿着 右边插入
            p[i].lc=p[k].rc;
            p[p[k].rc].pre=i;
            p[k].rc=i;
            p[i].pre=k;
            k=i;//注意这,
    
    
         }
    }
    int main()
    {
        int i;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            map1.clear();
            for(i=0;i<=n;i++)
            {
                p[i].pre=p[i].k=p[i].val=p[i].lc=p[i].rc=0;
            }
            for(i=1;i<=n;i++)
            {
                scanf("%d",&p[i].k);
                p[i].val=i;
            }
    
            qsort(p+1,n,sizeof(p[0]),cmp);
    
            for(i=1;i<=n;i++)
            {
                map1[p[i].k]=i;
            }
            build_tree();
            int q,a;
            while(m--)
            {
                scanf("%d",&q);
                 a=map1[q];
                if(p[a].pre==0){printf("-1\n");continue;}
                 a=p[a].pre;
                 if(p[a].pre==0){printf("-1\n");continue;}
                printf("%d\n",p[p[a].pre].k);
            }
        }
    
    }


  • 相关阅读:
    Java 链表
    知识点归列
    HTML和CSS必须知道的重点难点问题
    函数表达式
    javascript原型链
    canvas成长树
    checkbox选中问题
    使用vue-cli脚手架自定义iview主题
    AI学习吧-Redis操作-事务、订阅
    AI学习吧-REDIS-常识
  • 原文地址:https://www.cnblogs.com/acSzz/p/2606767.html
Copyright © 2011-2022 走看看