【团队赛组】2021-2022年度第三届全国大学生算法设计与编程挑战赛(秋季赛)——热身赛

目录

A题-这是一道压轴题

B题-这是一道大水题

D题-智慧数 


A题-这是一道压轴题

思路:本来想找递推式,没找到,干脆用指针模拟吧,不过这题描述不清晰,真正的意思是至多删除1次,也就是说可以不删除,当字符串全0或者全1就不用删除,输出n即可。

AC代码如下:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in) ;
        int n = input.nextInt() ;
        String s = input.next() ;
        char [] c = s.toCharArray() ;
        int max = 0, count = 0, left =0,  right = 0, l = 1;
        while(right<n && left<n){ //先判断原始字符串的最长连续子串
            while(right<n && c[left]==c[right]){
                right ++ ;
                count ++ ;
                max = Math.max(max, count) ;
            }
            if(right==n){
                break;
            }
            if(c[left] != c[right]){
                left = right ;
                count = 0 ;
            }
        }

        while(l<n && c[0]==c[l]){ //最左侧的不用管
            l ++ ;
        }
        if(l==n){ //字符串全部都是一种字符
            System.out.println(n);
        }else{
            int r = l ;
            while(r<n && l<n){
                while(r<n && c[l]==c[r]){ //找到中间的部分连续的相等字符的左右下标
                    r ++ ;
                }
                if(r==n){
                    break ;
                }
                    int sum = 0 ;
                    int temp = c[l-1] ;
                    left = l - 1 ;
                    right = r ;
                    while(left>=0 && temp==c[left]){
                        sum ++ ;
                        left -- ;
                    }
                    while(right<n && temp==c[right]){
                        sum ++ ;
                        right ++ ;
                    }
                    max = Math.max(max, sum) ; //求出删除后和原始的最大值
                    l = r ;
            }
            System.out.println(max);
        }

    }
}

B题-这是一道大水题

思路:树状数组,区间修改,单点查询。所有的加分总数求和为总的贡献值ans,每次操作0时候更新树状数组,对于操作1来说,总的贡献值ans减去x所在区间的贡献值就是答案。

import java.util.Scanner;

public class Main {
    static int n, m ;
    static long ans = 0 ;
    static long [] c = new long [200001] ;
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in) ;
        n = input.nextInt() ;
        m = input.nextInt() ;

        for(int i=0; i<m; i++){
            int op= input.nextInt() ;
            if(op==0){
                int x = input.nextInt() ;
                int y = input.nextInt() ;
                int k = input.nextInt() ;
                int num = (y-x+1) * k ;
                ans += num ;
                update(x, num) ;
                update(y+1, -num) ;
            }else{
                int x = input.nextInt() ;
                System.out.println(ans-query(x));
            }
        }
    }
    private static void update(int i, int a){
        while(i<=n){
            c[i] += a ;
            i += lowbit(i) ;
        }
    }
    private static long lowbit(int i){
        return (-i) & i ;
    }
    private static long  query(int i){
        long ans = 0 ;
        while(i>0){
            ans += c[i] ;
            i -= lowbit(i) ;
        }
        return ans ;
    }
}

D题-智慧数 

思路:从小到达依次寻找第n个智慧数即可。逻辑题。AC代码入下:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in) ;
        int n = input.nextInt() ;
        int x = 8 ;

        while(n>0){
            if(wise(x)){
                n -- ;
                if(n==0){
                    break ;
                }
                x ++ ;
            }else{
                x ++ ;
            }
        }
        System.out.println(x);
    }
    private static boolean wise(int x){
        for(int i=2; i<=x/2; i++){
            if(x%i==0 && (int)Math.sqrt(x*i)  * (int)Math.sqrt(x*i)== x*i){
                return true ;
            }
        }
        return false ;
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nuist__NJUPT

给个鼓励吧,谢谢你

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值