题解 | 牛客小白月赛98 DEF Java

骰子魔术

https://ac.nowcoder.com/acm/contest/85598/A

DEF Java

D 切割 01 串 2.0

区间动态规划,前缀和记录分别01的个数,从小区间开始更新,每个区间的方案数都是由旗下的分割更新而来的,时间复杂度O(n^3)

import java.util.*;
public class Main{
    public static void main(String args[]){
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt(),l=sc.nextInt(),r=sc.nextInt(),pre[][]=new int[n+1][2],ans[][]=new int[n][n];
        String s=sc.next();
        for(int i=1;i<=n;i++){
            pre[i]=pre[i-1].clone();
            pre[i][s.charAt(i-1)-'0']++;
        }
        for(int d=1;d<n;d++){
            for(int i=0;i<n-d;i++){
                for(int j=i;j<i+d;j++){
                    int c=Math.abs((pre[j+1][0]-pre[i][0])-(pre[i+d+1][1]-pre[j+1][1]));
                    if(c>=l&&c<=r){
                        ans[i][i+d]=Math.max(ans[i][i+d],1+ans[i][j]+ans[j+1][i+d]);
                    }
                }
            }
        }
        System.out.println(ans[0][n-1]);
    }
}

E and xor or

考虑每个二进制位,只有在区间内,该位既有1又有0的时候,这个以为计算之后才会是1,因此在固定右端点,左端点越靠左,计算得到的数越大,采用二分寻找两次端点,中间的部分符合要求,时间复杂度O(nlog(nC)),其中C==63

import java.util.*;
public class Main{
    public static void main(String args[]){
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt(),k1=sc.nextInt(),k2=sc.nextInt(),pre[][]=new int[n+1][63];
        for(int i=1;i<=n;i++){
            long a=sc.nextLong();
            pre[i]=pre[i-1].clone();
            for(int j=0;j<63;j++){
                pre[i][j]+=(int)(a>>j&1);
            }
        }
        long ans=0;
        for(int i=1;i<=n;i++){
            ans+=find(pre,i,k1)-find(pre,i,k2);
        }
        System.out.println(ans);
    }
    static int find(int pre[][],int idx,int k){
        int l=0,r=idx-1;
        while(l<r){
            int mid=(l+r)>>1;
            if(check(pre,mid,idx,k)){
                r=mid;
            }
            else{
                l=mid+1;
            }
            if(l==r-1){
                if(check(pre,l,idx,k)){
                    r=l;
                }
                break;
            }
        }
        return r;
    }
    static boolean check(int pre[][],int l,int r,int k){
        for(int i=62;i>=k;i--){
            if(pre[r][i]!=pre[l][i]&&pre[r][i]-pre[l][i]!=r-l){
                return false;
            }
        }
        return true;
    }
}

F 绝妙的手法

据说官解也不对,让子弹飞一会儿。。。

全部评论

相关推荐

Hakasee:我的简历和你的基本一样,上周去了上海,boss投了三百家, 三家线下面试 第一家没有做题,全是八股和项目,因为第一次面试不怎么熟练,挂了 第二家,给你几个题目(①css垂直居中文字,字体每两秒闪烁一下以及点击弹窗,②给你一个链接,实现可视化地图,③然后是八股,图片性能优化,以及对图片app有什么想法),45分钟内做完,然后老板面试) 第三家特别偏僻,有点阴森,到了之后让了一个工位给我,有四个题目,①格式化时间 年月日当前时间星期几② 正则表达式提取新闻文字,③在文本域输入文字生成选择题以及选项④生成商品排版还是什么来着 三家都是不超过50人的小公司 两家线上牛客笔试(卡伦特,七牛云,但是笔试不仅要考前端,还要考后端,算法,甚至数学题 我的建议是如果只做了这两个vue项目且不怎么熟练的情况下,先沉淀沉淀,把react学了,上海好的公司基本都是react查看图片
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务