题解 | 牛客周赛 Round 63 DEF Java题解

小红的好数

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

DEF Java题解~~~代码已去除冗余,并保留必要的注释

D 小红的行列式构造

好烦啊,瞎做呗,令上边俩角的元素相同,下边俩角的元素相同,可以消掉一部分,剩下的代数式分解因式即可拼凑,时间复杂度O(1)

import java.util.*;
public class Main{
    public static void main(String args[]){
        Scanner sc=new Scanner(System.in);
        System.out.println("99 100 99\n101 1 "+(sc.nextInt()+101)+"\n1 1 1");
    }
}

E 小红的 red 计数

寻找目标子序列的数目,可以找出任意分解在不同区间的贡献值,考虑全部情况相加,大串的数量跟串的数量(贡献)有关,减小复杂度可用分层前缀后缀和,时间复杂度O(n+q)

import java.util.*;
import java.io.*;
public class Main{
    static String red="red";
    static Map<String,Integer> map=new HashMap<>();
    static{
        for(int i=0;i<3;i++){
            for(int j=i;j<3;j++){
                map.put(red.substring(i,j+1),map.size());
            }
        }
    }
    public static void main(String args[]) throws IOException{
        BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));
        String arr[]=bf.readLine().split(" ");
        int n=Integer.parseInt(arr[0]),q=Integer.parseInt(arr[1]);
        String s=bf.readLine();
        long pre1[][]=new long[n+5][7],pre2[][]=new long[n+5][7];
        for(int i=1;i<=n;i++){
            pre1[i]=pre1[i-1].clone();
            char c=s.charAt(i-1);
            int idx=red.indexOf(c);
            if(idx>=0){
                for(int j=idx-1;j>=0;j--){
                    pre1[i][map.get(red.substring(j,idx+1))]+=pre1[i-1][map.get(red.substring(j,idx))];
                }
                pre1[i][map.get(String.valueOf(c))]++;
            }
        }
        for(int i=n;i>0;i--){
            pre2[i]=pre2[i+1].clone();
            char c=s.charAt(i-1);
            int idx=red.indexOf(c);
            if(idx>=0){
                for(int j=idx-1;j>=0;j--){
                    pre2[i][map.get(red.substring(j,idx+1))]+=pre2[i+1][map.get(red.substring(j,idx))];
                }
                pre2[i][map.get(String.valueOf(c))]++;
            }
        }
        for(int i=0;i<q;i++){
            arr=bf.readLine().split(" ");
            int l=Integer.parseInt(arr[0]),r=Integer.parseInt(arr[1]);
            long ans=0;
            for(int j=0;j<=3;j++){
                for(int k=j;k<=3;k++){
                    ans+=find1(pre1,1,l-1,substring(red,0,j-1))*find2(pre2,l,r,substring(red,j,k-1))*find1(pre1,r+1,n,substring(red,k,2));
                }
            }
            bw.write(ans+"\n");
        }
        bw.flush();
    }
    static long find1(long pre1[][],int l,int r,String s){
        if(s.length()>r-l+1){
            return 0;
        }
        if(s.length()==0){
            return 1;
        }
        long ans=pre1[r][map.get(s)]-pre1[l-1][map.get(s)];
        for(int i=1;i<s.length();i++){
            ans-=find1(pre1,1,l-1,s.substring(0,i))*find1(pre1,l,r,s.substring(i));
        }
        return ans;
    }
    static long find2(long pre2[][],int l,int r,String s){
        if(s.length()>r-l+1){
            return 0;
        }
        if(s.length()==0){
            return 1;
        }
        long ans=pre2[l][map.get(s)]-pre2[r+1][map.get(s)];
        for(int i=1;i<s.length();i++){
            ans-=find2(pre2,r+1,pre2.length-5,s.substring(0,i))*find2(pre2,l,r,s.substring(i));
        }
        return ans;
    }
    static String substring(String s,int l,int r){
        return l>r?"":s.substring(l,r+1);
    }
}

F 小红开灯

利用线性基,将每个灯所能够造成的影响用128位的二进制数表示,高斯消元至上三角矩阵,之后按位尝试变为1,由于Java不含int128,因此本代码中部分位运算采用手动处理,时间复杂度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(),p[][]=new int[n][2],idx[]=new int[n];
        long mask[][]=new long[n][2],start[]=new long[2],xor[][]=new long[n][2],ans[]=new long[2];//假设每一维的比特数最大为60位
        String s=sc.next();
        for(int i=0;i<n;i++){
            idx[i]=i;
            p[i]=new int[]{sc.nextInt(),sc.nextInt()};
            start[i/60]|=(long)(s.charAt(i)-'0')<<(i%60);
            xor[i][i/60]|=1L<<(i%60);
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(p[i][0]==p[j][0]||p[i][1]==p[j][1]){
                    mask[i][j/60]|=1L<<(j%60);
                }
            }
        }
        for(int i=0;i<n;i++){
            int curIdx=i;
            for(int j=i+1;j<n;j++){
                if(findMaxBit(mask[idx[curIdx]])<findMaxBit(mask[idx[j]])){
                    curIdx=j;
                }
            }
            if(curIdx!=i){
                idx[i]^=idx[curIdx];
                idx[curIdx]^=idx[i];
                idx[i]^=idx[curIdx];
            }
            int cur=findMaxBit(mask[idx[i]]);
            if(cur==-1){
                break;
            }
            for(int j=i+1;j<n;j++){
                if(findMaxBit(mask[idx[j]])==cur){
                    mask[idx[j]]=findXor(mask[idx[j]],mask[idx[i]]);
                    xor[idx[j]]=findXor(xor[idx[j]],xor[idx[i]]);
                }
            }
        }
        for(int i=n-1,j=0;i>=0;i--){
            if((start[i/60]>>(i%60)&1)==0){
                while(j<n&&findMaxBit(mask[idx[j]])>i){
                    j++;
                }
                if(j==n||findMaxBit(mask[idx[j]])<i){
                    System.out.println("-1");
                    return;
                }
                start=findXor(start,mask[idx[j]]);
                ans=findXor(ans,xor[idx[j]]);
            }
        }
        System.out.println(Long.bitCount(ans[0])+Long.bitCount(ans[1]));
        for(int i=0;i<n;i++){
            if((ans[i/60]>>(i%60)&1)==1){
                System.out.print((i+1)+" ");
            }
        }
    }
    static long[] findXor(long a[],long b[]){
        //128位的异或
        return new long[]{a[0]^b[0],a[1]^b[1]};
    }
    static int findMaxBit(long a[]){
        for(int i=100;i>=0;i--){
            if((a[i/60]>>(i%60)&1)==1){
                return i;
            }
        }
        return -1;
    }
}
全部评论

相关推荐

不愿透露姓名的神秘牛友
07-08 13:05
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-08 11:16
点赞 评论 收藏
分享
避坑恶心到我了大家好,今天我想跟大家聊聊我在成都千子成智能科技有限公司(以下简称千子成)的求职经历,希望能给大家一些参考。千子成的母公司是“同创主悦”,主要经营各种产品,比如菜刀、POS机、电话卡等等。听起来是不是有点像地推销售公司?没错,就是那种类型的公司。我当时刚毕业,急需一份临时工作,所以在BOSS上看到了千子成的招聘信息。他们承诺无责底薪5000元,还包住宿,这吸引了我。面试的时候,HR也说了同样的话,感觉挺靠谱的。于是,我满怀期待地等待结果。结果出来后,我通过了面试,第二天就收到了试岗通知。试岗的内容就是地推销售,公司划定一个区域,然后你就得见人就问,问店铺、问路人,一直问到他们有意向为止。如果他们有兴趣,你就得摇同事帮忙推动,促进成交。说说一天的工作安排吧。工作时间是从早上8:30到晚上18:30。早上7点有人叫你起床,收拾后去公司,然后唱歌跳舞(销售公司都这样),7:55早课(类似宣誓),8:05同事间联系销售话术,8:15分享销售技巧,8:30经理训话。9:20左右从公司下市场,公交、地铁、自行车自费。到了市场大概10点左右,开始地推工作。中午吃饭时间大约是12:00,公司附近的路边盖饭面馆店自费AA,吃饭时间大约40分钟左右。吃完饭后继续地推工作,没有所谓的固定中午午休时间。下午6点下班后返回公司,不能直接下班,需要与同事交流话术,经理讲话洗脑。正常情况下9点下班。整个上班的一天中,早上到公司就是站着的,到晚上下班前都是站着。每天步数2万步以上。公司员工没有自己的工位,百来号人挤在一个20平方米的空间里听经理洗脑。白天就在市场上奔波,公司的投入成本几乎只有租金和工资,没有中央空调。早上2小时,晚上加班2小时,纯蒸桑拿。没有任何福利,节假日也没有3倍工资之类的。偶尔会有冲的酸梅汤和西瓜什么的。公司的晋升路径也很有意思:新人—组长—领队—主管—副经理—经理。要求是业绩和团队人数,类似传销模式,把人留下来。新人不能加微信、不能吐槽公司、不能有负面情绪、不能谈恋爱、不能说累。在公司没有任何坐的地方,不能依墙而坐。早上吃早饭在公司外面的安全通道,未到上班时间还会让你吃快些不能磨蹭。总之就是想榨干你。复试的时候,带你的师傅会给你营造一个钱多事少离家近的工作氛围,吹嘘工资有多高、还能吹自己毕业于好大学。然后让你早点来公司、无偿加班、抓住你可能不会走的心思进一步压榨你。总之,大家在找工作的时候一定要擦亮眼睛,避免踩坑!———来自网友
qq乃乃好喝到咩噗茶:不要做没有专业门槛的工作
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-10 15:58
投个小米提前批试试水,先投一个岗位看看形势,不行就再沉淀一下投第二个岗位,莫辜负
Java抽象带篮子:我嘞个骚刚,已经开始研发6g了吗
投递小米集团等公司7个岗位
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

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